Exclusion tags for notifications. Place text in certain tags to only send that text for a certain media type.

Simple check which disables the Enable IP logging checkbox if Logs folder not set.
Some styling changes.
This commit is contained in:
Tim 2015-07-28 01:50:19 +02:00
parent 8ed94fa122
commit 2b187f0bf3
3 changed files with 147 additions and 28 deletions

View file

@ -1288,10 +1288,10 @@ input[type="color"],
margin-top: 5px; margin-top: 5px;
color: #fff; color: #fff;
border: 0px solid #444; border: 0px solid #444;
background: #333; background: #555;
height: 24px; height: 24px;
padding: 2px 5px 2px 12px; padding: 2px 5px 2px 12px;
background-color: #3a3a3a; background-color: #555;
border-radius: 14.5px; border-radius: 14.5px;
transition: background-color .3s; transition: background-color .3s;
} }

View file

@ -265,7 +265,7 @@
</div> </div>
<div class="checkbox"> <div class="checkbox">
<input type="checkbox" id="ip_logging_enable" name="ip_logging_enable" value="1" ${config['ip_logging_enable']}> Enable IP Logging <input type="checkbox" id="ip_logging_enable" name="ip_logging_enable" value="1" ${config['ip_logging_enable']}> Enable IP Logging
<span id="debugLogCheck" style="color: red; padding-left: 10px;"></span> <span id="debugLogCheck" style="color: #eb8600; padding-left: 10px;"></span>
<p class="help-block"> <p class="help-block">
Enable this to attempt to log the IP address of the user. Enable this to attempt to log the IP address of the user.
</p> </p>
@ -304,6 +304,10 @@
You can set custom formatted text for each type of notification. You can set custom formatted text for each type of notification.
Click <a href="#notify-text-sub-modal" data-toggle="modal">here</a> for a list of available parameters which can be used. Click <a href="#notify-text-sub-modal" data-toggle="modal">here</a> for a list of available parameters which can be used.
</p> </p>
<p class="help-block">
You can also add tags to exclude certain text depending on the media type. Click
<a href="#notify-text-tags-modal" data-toggle="modal">here</a> to view usage information.
</p>
<br/> <br/>
<ul id="accordion" class="accordion"> <ul id="accordion" class="accordion">
<li> <li>
@ -592,49 +596,57 @@
<td width="150"><strong>{title}</strong></td> <td width="150"><strong>{title}</strong></td>
<td>The title of the item being played back.</td> <td>The title of the item being played back.</td>
</tr> </tr>
<tr>
<td width="150"><strong>{show_name}</strong></td>
<td>The title of the TV series being played back.</td>
</tr>
<tr>
<td width="150"><strong>{episode_name}</strong></td>
<td>The title of the episode being played back.</td>
</tr>
<tr> <tr>
<td width="150"><strong>{transcode_decision}</strong></td> <td width="150"><strong>{transcode_decision}</strong></td>
<td>Returns the transcode decisions for the media item.</td> <td>The transcode decisions for the media item.</td>
</tr> </tr>
<tr> <tr>
<td width="150"><strong>{year}</strong></td> <td width="150"><strong>{year}</strong></td>
<td>Returns the release year for the media item.</td> <td>The release year for the media item.</td>
</tr> </tr>
<tr> <tr>
<td width="150"><strong>{studio}</strong></td> <td width="150"><strong>{studio}</strong></td>
<td>Returns the studio for the media item.</td> <td>The studio for the media item.</td>
</tr> </tr>
<tr> <tr>
<td width="150"><strong>{content_rating}</strong></td> <td width="150"><strong>{content_rating}</strong></td>
<td>Returns the content rating for the media item. E.g. TV-MA, TV-PG, etc.</td> <td>The content rating for the media item. E.g. TV-MA, TV-PG, etc.</td>
</tr> </tr>
<tr> <tr>
<td width="150"><strong>{summary}</strong></td> <td width="150"><strong>{summary}</strong></td>
<td>Returns the a short plot summary for the media item.</td> <td>A short plot summary for the media item.</td>
</tr> </tr>
<tr> <tr>
<td width="150"><strong>{season_num}</strong></td> <td width="150"><strong>{season_num}</strong></td>
<td>Returns the season number for the media item if item is episode.</td> <td>The season number for the media item if item is episode.</td>
</tr> </tr>
<tr> <tr>
<td width="150"><strong>{episode_num}</strong></td> <td width="150"><strong>{episode_num}</strong></td>
<td>Returns the episode number for the media item if item is episode.</td> <td>The episode number for the media item if item is episode.</td>
</tr> </tr>
<tr> <tr>
<td width="150"><strong>{rating}</strong></td> <td width="150"><strong>{rating}</strong></td>
<td>Returns the rating (out of 10) for the item.</td> <td>The rating (out of 10) for the item.</td>
</tr> </tr>
<tr> <tr>
<td width="150"><strong>{duration}</strong></td> <td width="150"><strong>{duration}</strong></td>
<td>Returns the duration (in minutes) for the item.</td> <td>The duration (in minutes) for the item.</td>
</tr> </tr>
<tr> <tr>
<td width="150"><strong>{progress}</strong></td> <td width="150"><strong>{progress}</strong></td>
<td>Returns the last reported offset (in minutes) for the item.</td> <td>The last reported offset (in minutes) for the item.</td>
</tr> </tr>
<tr> <tr>
<td width="150"><strong>{progress_percent}</strong></td> <td width="150"><strong>{progress_percent}</strong></td>
<td>Returns the last reported progress percent for the item.</td> <td>The last reported progress percent for the item.</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@ -643,6 +655,41 @@
<div class="modal-footer"> <div class="modal-footer">
</div> </div>
</div> </div>
<div id="notify-text-tags-modal" class="modal hide fade" tabindex="-1" role="dialog"
aria-labelledby="notify-text-tags-modal" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i
class="fa fa-remove"></i></button>
<h3>Notification exclusion tags</h3>
</div>
<div class="modal-body">
<div>
<div class="wellheader">
<h4>Movie Tag <strong>&lt;movie&gt;&lt;/movie&gt;</strong></h4>
</div>
<div>
<p class="help-block">All text inside a <strong>movie</strong> tag will only be sent when the media item being played back is a movie.</p>
<pre>Example: {user} has started playing {title} &lt;movie&gt;({year})&lt;/movie&gt;</pre>
</div>
<div class="wellheader">
<h4>TV Tag <strong>&lt;tv&gt;&lt;/tv&gt;</strong></h4>
</div>
<div>
<p class="help-block">All text inside a <strong>tv</strong> tag will only be sent when the media item being played back is an episode.</p>
<pre>Example: {user} has started playing {title} &lt;tv&gt;(S{season_num}E{episode_num})&lt;/tv&gt;</pre>
</div>
<div class="wellheader">
<h4>Music Tag <strong>&lt;music&gt;&lt;/music&gt;</strong></h4>
</div>
<div>
<p class="help-block">All text inside a <strong>music</strong> tag will only be sent when the media item being played back is a music track.</p>
<pre>Example: {user} has started playing {title} &lt;music&gt;(Track {episode_num})&lt;/music&gt;</pre>
</div>
</div>
</div>
<div class="modal-footer">
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -651,7 +698,6 @@
<%def name="javascriptIncludes()"> <%def name="javascriptIncludes()">
<script src="interfaces/default/js/parsley.min.js"></script> <script src="interfaces/default/js/parsley.min.js"></script>
<script src="interfaces/default/js/jquery.highlighttextarea.min.js"></script>
<script> <script>
$(document).ready(function() { $(document).ready(function() {
@ -934,6 +980,23 @@ $(document).ready(function() {
} }
}); });
// Check to see if our logs folder is set before allowing IP logging to be enabled.
checkLogsPath();
$("#pms_logs_folder").change(function() {
checkLogsPath();
});
function checkLogsPath() {
if ($("#pms_logs_folder").val() == '') {
$("#debugLogCheck").html("You must first define your Plex Server Logs folder path under the Extra Settings tab.");
$("#ip_logging_enable").attr("disabled", true);
} else {
$("#ip_logging_enable").attr("disabled", false);
$("#debugLogCheck").html("");
}
}
var accordion = new Accordion($('#accordion'), false); var accordion = new Accordion($('#accordion'), false);
}); });
</script> </script>

View file

@ -153,6 +153,7 @@ def set_notify_state(session, state, agent_info):
def build_notify_text(session, state): def build_notify_text(session, state):
from plexpy import pmsconnect, helpers from plexpy import pmsconnect, helpers
import re
# Get the server name # Get the server name
pms_connect = pmsconnect.PmsConnect() pms_connect = pmsconnect.PmsConnect()
@ -167,12 +168,59 @@ def build_notify_text(session, state):
logger.error(u"PlexPy Notifier :: Unable to retrieve metadata for rating_key %s" % str(session['rating_key'])) logger.error(u"PlexPy Notifier :: Unable to retrieve metadata for rating_key %s" % str(session['rating_key']))
return [] return []
# TODO: There must be a better way to do this. Laziness.
# Check for exclusion tags
if session['media_type'] == 'episode':
on_start_subject = strip_tag(re.sub('<movie>[^>]+.</movie>|<music>[^>]+.</music>', '',
plexpy.CONFIG.NOTIFY_ON_START_SUBJECT_TEXT))
on_start_body = strip_tag(re.sub('<movie>[^>]+.</movie>|<music>[^>]+.</music>', '',
plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT))
on_stop_subject = strip_tag(re.sub('<movie>[^>]+.</movie>|<music>[^>]+.</music>', '',
plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT))
on_stop_body = strip_tag(re.sub('<movie>[^>]+.</movie>|<music>[^>]+.</music>', '',
plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT))
on_watched_subject = strip_tag(re.sub('<movie>[^>]+.</movie>|<music>[^>]+.</music>', '',
plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT))
on_watched_body = strip_tag(re.sub('<movie>[^>]+.</movie>|<music>[^>]+.</music>', '',
plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT))
elif session['media_type'] == 'movie':
on_start_subject = strip_tag(re.sub('<tv>[^>]+.</tv>|<music>[^>]+.</music>', '',
plexpy.CONFIG.NOTIFY_ON_START_SUBJECT_TEXT))
on_start_body = strip_tag(re.sub('<tv>[^>]+.</tv>|<music>[^>]+.</music>', '',
plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT))
on_stop_subject = strip_tag(re.sub('<tv>[^>]+.</tv>|<music>[^>]+.</music>', '',
plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT))
on_stop_body = strip_tag(re.sub('<tv>[^>]+.</tv>|<music>[^>]+.</music>', '',
plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT))
on_watched_subject = strip_tag(re.sub('<tv>[^>]+.</tv>|<music>[^>]+.</music>', '',
plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT))
on_watched_body = strip_tag(re.sub('<tv>[^>]+.</tv>|<music>[^>]+.</music>', '',
plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT))
elif session['media_type'] == 'track':
on_start_subject = strip_tag(re.sub('<tv>[^>]+.</tv>|<movie>[^>]+.</movie>', '',
plexpy.CONFIG.NOTIFY_ON_START_SUBJECT_TEXT))
on_start_body = strip_tag(re.sub('<tv>[^>]+.</tv>|<movie>[^>]+.</movie>', '',
plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT))
on_stop_subject = strip_tag(re.sub('<tv>[^>]+.</tv>|<movie>[^>]+.</movie>', '',
plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT))
on_stop_body = strip_tag(re.sub('<tv>[^>]+.</tv>|<movie>[^>]+.</movie>', '',
plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT))
on_watched_subject = strip_tag(re.sub('<tv>[^>]+.</tv>|<movie>[^>]+.</movie>', '',
plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT))
on_watched_body = strip_tag(re.sub('<tv>[^>]+.</tv>|<movie>[^>]+.</movie>', '',
plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT))
else:
on_start_subject = plexpy.CONFIG.NOTIFY_ON_START_SUBJECT_TEXT
on_start_body = plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT
on_stop_subject = plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT
on_stop_body = plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT
on_watched_subject = plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT
on_watched_body = plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT
# Create a title # Create a title
if session['media_type'] == 'episode': if session['media_type'] == 'episode':
full_title = '%s - %s (%sx%s)' % (session['grandparent_title'], full_title = '%s - %s' % (session['grandparent_title'],
session['title'], session['title'])
item_metadata['parent_index'],
item_metadata['index'])
elif session['media_type'] == 'track': elif session['media_type'] == 'track':
full_title = '%s - %s' % (session['grandparent_title'], full_title = '%s - %s' % (session['grandparent_title'],
session['title']) session['title'])
@ -202,6 +250,8 @@ def build_notify_text(session, state):
'user': session['friendly_name'], 'user': session['friendly_name'],
'player': session['player'], 'player': session['player'],
'title': full_title, 'title': full_title,
'show_name': item_metadata['grandparent_title'],
'episode_name': item_metadata['title'],
'platform': session['platform'], 'platform': session['platform'],
'media_type': session['media_type'], 'media_type': session['media_type'],
'transcode_decision': transcode_decision, 'transcode_decision': transcode_decision,
@ -226,14 +276,14 @@ def build_notify_text(session, state):
session['player'], session['player'],
full_title) full_title)
if plexpy.CONFIG.NOTIFY_ON_START_SUBJECT_TEXT and plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT: if on_start_subject and on_start_body:
try: try:
subject_text = plexpy.CONFIG.NOTIFY_ON_START_SUBJECT_TEXT.format(**available_params) subject_text = on_start_subject.format(**available_params)
except: except:
logger.error(u"PlexPy Notifier :: Unable to parse custom notification subject. Using default.") logger.error(u"PlexPy Notifier :: Unable to parse custom notification subject. Using default.")
try: try:
body_text = plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT.format(**available_params) body_text = on_start_body.format(**available_params)
except: except:
logger.error(u"PlexPy Notifier :: Unable to parse custom notification body. Using default.") logger.error(u"PlexPy Notifier :: Unable to parse custom notification body. Using default.")
@ -246,14 +296,14 @@ def build_notify_text(session, state):
session['player'], session['player'],
full_title) full_title)
if plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT and plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT: if on_stop_subject and on_stop_body:
try: try:
subject_text = plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT.format(**available_params) subject_text = on_stop_subject.format(**available_params)
except: except:
logger.error(u"PlexPy Notifier :: Unable to parse custom notification subject. Using default.") logger.error(u"PlexPy Notifier :: Unable to parse custom notification subject. Using default.")
try: try:
body_text = plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT.format(**available_params) body_text = on_stop_body.format(**available_params)
except: except:
logger.error(u"PlexPy Notifier :: Unable to parse custom notification body. Using default.") logger.error(u"PlexPy Notifier :: Unable to parse custom notification body. Using default.")
@ -266,14 +316,14 @@ def build_notify_text(session, state):
session['player'], session['player'],
full_title) full_title)
if plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT and plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT: if on_watched_subject and on_watched_body:
try: try:
subject_text = plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT.format(**available_params) subject_text = on_watched_subject.format(**available_params)
except: except:
logger.error(u"PlexPy Notifier :: Unable to parse custom notification subject. Using default.") logger.error(u"PlexPy Notifier :: Unable to parse custom notification subject. Using default.")
try: try:
body_text = plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT.format(**available_params) body_text = on_watched_body.format(**available_params)
except: except:
logger.error(u"PlexPy Notifier :: Unable to parse custom notification body. Using default.") logger.error(u"PlexPy Notifier :: Unable to parse custom notification body. Using default.")
@ -282,3 +332,9 @@ def build_notify_text(session, state):
return [subject_text, body_text] return [subject_text, body_text]
else: else:
return None return None
def strip_tag(data):
import re
p = re.compile(r'<.*?>')
return p.sub('', data)