mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-08 06:00:51 -07:00
Add custom modifiers to notification text
This commit is contained in:
parent
fdff9d7454
commit
718049b9f3
3 changed files with 140 additions and 34 deletions
|
@ -113,6 +113,7 @@
|
|||
<div role="tabpanel" class="tab-pane" id="tabs-notify_triggers">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<label>Notification Triggers</label>
|
||||
<p class="help-block">
|
||||
Select items that will trigger a notification for this ${notifier['agent_label']} notifiation agent.
|
||||
</p>
|
||||
|
@ -129,6 +130,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" id="tabs-notify_conditions">
|
||||
<label>Notification Conditions</label>
|
||||
<p class="help-block">
|
||||
Add custom notification conditions.
|
||||
<a href="#notify-text-sub-modal" data-toggle="modal">Click here</a> for a description of all the parameters.
|
||||
|
@ -152,6 +154,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" id="tabs-notify_text">
|
||||
<label>Notification Text</label>
|
||||
<p class="help-block">
|
||||
% if notifier['agent_name'] == 'scripts':
|
||||
Set the custom arguments passed to the script for each type of notification.
|
||||
|
@ -160,6 +163,10 @@
|
|||
% endif
|
||||
<a href="#notify-text-sub-modal" data-toggle="modal">Click here</a> for a list of available parameters which can be used.
|
||||
</p>
|
||||
<p class="help-block">
|
||||
You can also add text modifiers to change the case or slice parameters with a list of items.
|
||||
<a href="#notify-text-modifiers-modal" data-toggle="modal">Click here</a> to view usage information.
|
||||
</p>
|
||||
<p class="help-block">
|
||||
You can also add tags to exclude certain text depending on the media type.
|
||||
<a href="#notify-text-tags-modal" data-toggle="modal">Click here</a> to view usage information.
|
||||
|
@ -219,48 +226,61 @@
|
|||
</ul>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" id="tabs-test_notifications">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<p class="help-block">
|
||||
Test if ${notifier['agent_label']} notifications are working. Check the <a href="logs">logs</a> for troubleshooting.
|
||||
</p>
|
||||
<p class="help-block">
|
||||
Note: Test with the real values since parameters will not be substituted.
|
||||
(i.e. Use <span class="inline-pre">"Game of Thrones"</span> not <span class="inline-pre">{title}</span>)
|
||||
</p>
|
||||
% if notifier['agent_name'] == 'scripts':
|
||||
<div class="form-group">
|
||||
<label for="test_script">Script</label>
|
||||
<label>Test Notifications</label>
|
||||
<p class="help-block">
|
||||
Test if ${notifier['agent_label']} notifications are working. Check the <a href="logs">logs</a> for troubleshooting.
|
||||
</p>
|
||||
<p class="help-block">
|
||||
Note: Test with the real values since parameters will not be substituted.
|
||||
(i.e. Use <span class="inline-pre">"Game of Thrones"</span> not <span class="inline-pre">{title}</span>)
|
||||
</p>
|
||||
% if notifier['agent_name'] == 'scripts':
|
||||
<div class="form-group">
|
||||
<label for="test_script">Script</label>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<select class="form-control" id="test_script" name="test_script">
|
||||
% for key, value in sorted(notifier['config_options'][2]['select_options'].iteritems()):
|
||||
<option value="${key}">${value}</option>
|
||||
% endfor
|
||||
</select>
|
||||
<p class="help-block">Choose the script to test.</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="test_script_args">Script Arguments</label>
|
||||
</div>
|
||||
<p class="help-block">Choose the script to test.</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="test_script_args">Script Arguments</label>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<input class="form-control" type="text" id="test_script_args" name="test_script_args" value="">
|
||||
<p class="help-block">Set custom arguments passed to the script.</p>
|
||||
</div>
|
||||
% else:
|
||||
<div class="form-group">
|
||||
<label for="test_subject">Subject Line</label>
|
||||
</div>
|
||||
<p class="help-block">Set custom arguments passed to the script.</p>
|
||||
</div>
|
||||
% else:
|
||||
<div class="form-group">
|
||||
<label for="test_subject">Subject Line</label>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<input class="form-control" type="text" id="test_subject" name="test_subject" value="PlexPy">
|
||||
<p class="help-block">Set a custom subject line.</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="test_body">Message Body</label>
|
||||
</div>
|
||||
<p class="help-block">Set a custom subject line.</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="test_body">Message Body</label>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<input class="form-control" type="text" id="test_body" name="test_body" value="Test notification">
|
||||
<p class="help-block">Set a custom body.</p>
|
||||
</div>
|
||||
% endif
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<input type="button" class="btn btn-bright" id="test_notifier" name="test_notifier" value="Test ${notifier['agent_label']}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="help-block">Set a custom body.</p>
|
||||
</div>
|
||||
% endif
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<input type="button" class="btn btn-bright" id="test_notifier" name="test_notifier" value="Test ${notifier['agent_label']}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1342,6 +1342,57 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="notify-text-modifiers-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="notify-text-modifiers-modal">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="fa fa-remove"></i></button>
|
||||
<h4 class="modal-title">Notification Text Modifiers</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div>
|
||||
<div>
|
||||
<h4>Case Modifiers</h4>
|
||||
</div>
|
||||
<div>
|
||||
<p class="help-block">Notification parameters with the <span class="inline-pre">!u</span> modifier will be converted to uppercase.</p>
|
||||
<p><strong style="color: #fff;">Example:</strong></p>
|
||||
<pre>{video_codec} --> hevc
|
||||
{video_codec!u} --> HEVC</pre>
|
||||
</div>
|
||||
<div>
|
||||
<p class="help-block">Notification parameters with the <span class="inline-pre">!l</span> modifier will be converted to lowercase.</p>
|
||||
<p><strong style="color: #fff;">Example:</strong></p>
|
||||
<pre>{content_rating} --> TV-PG
|
||||
{content_rating!l} --> tv-pg</pre>
|
||||
</div>
|
||||
<div style="padding-bottom: 10px;">
|
||||
<p class="help-block">Notification parameters with the <span class="inline-pre">!c</span> modifier will be converted to title case.</p>
|
||||
<p><strong style="color: #fff;">Example:</strong></p>
|
||||
<pre>{media_type} --> movie
|
||||
{media_type!c} --> Movie</pre>
|
||||
</div>
|
||||
<div>
|
||||
<h4>List Slicing</h4>
|
||||
</div>
|
||||
<div>
|
||||
<p class="help-block">
|
||||
Notification parameters which have a list of items can be sliced with a slice formatter <span class="inline-pre">:[X:Y]</span> to limit the number of items.
|
||||
Note: the first item in the list is numbered <span class="inline-pre">0</span>.
|
||||
</p>
|
||||
<p><strong style="color: #fff;">Example:</strong></p>
|
||||
<pre>{actors:[0]} --> Only include the 1st actor (Actors: 0)
|
||||
{actors:[:4]} --> Only the first 4 actors (Actors: 0, 1, 2, 3)
|
||||
{actors:[2:]} --> Only the 3rd to last actors (Actors: 2, 3, 4, ...)
|
||||
{actors:[1:5]} --> Only the 2nd to 5th actors (Actors: 1, 2, 3, 4)</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="notifier-text-preview-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="notifier-text-preview-modal">
|
||||
</div>
|
||||
<div id="changelog-modal" class="modal fade wide" tabindex="-1" role="dialog" aria-labelledby="changelog-modal">
|
||||
|
|
|
@ -21,6 +21,7 @@ import json
|
|||
from operator import itemgetter
|
||||
import os
|
||||
import re
|
||||
from string import Formatter
|
||||
import threading
|
||||
import time
|
||||
|
||||
|
@ -911,9 +912,11 @@ def build_notify_text(subject='', body='', notify_action=None, parameters=None,
|
|||
if test:
|
||||
return subject, body
|
||||
|
||||
custom_formatter = CustomFormatter()
|
||||
|
||||
if agent_id == 15:
|
||||
try:
|
||||
script_args = [unicode(arg).format(**parameters) for arg in subject.split()]
|
||||
script_args = [custom_formatter.format(unicode(arg), **parameters) for arg in subject.split()]
|
||||
except LookupError as e:
|
||||
logger.error(u"PlexPy NotificationHandler :: Unable to parse field %s in script argument. Using fallback." % e)
|
||||
script_args = []
|
||||
|
@ -924,7 +927,7 @@ def build_notify_text(subject='', body='', notify_action=None, parameters=None,
|
|||
script_args = []
|
||||
|
||||
try:
|
||||
subject = unicode(subject).format(**parameters)
|
||||
subject = custom_formatter.format(unicode(subject), **parameters)
|
||||
except LookupError as e:
|
||||
logger.error(u"PlexPy NotificationHandler :: Unable to parse field %s in notification subject. Using fallback." % e)
|
||||
subject = unicode(default_subject).format(**parameters)
|
||||
|
@ -933,7 +936,7 @@ def build_notify_text(subject='', body='', notify_action=None, parameters=None,
|
|||
subject = unicode(default_subject).format(**parameters)
|
||||
|
||||
try:
|
||||
body = unicode(body).format(**parameters)
|
||||
body = custom_formatter.format(unicode(body), **parameters)
|
||||
except LookupError as e:
|
||||
logger.error(u"PlexPy NotificationHandler :: Unable to parse field %s in notification body. Using fallback." % e)
|
||||
body = unicode(default_body).format(**parameters)
|
||||
|
@ -1179,4 +1182,36 @@ def get_themoviedb_info(rating_key=None, media_type=None, themoviedb_id=None):
|
|||
if req_msg:
|
||||
logger.debug(u"PlexPy NotificationHandler :: Request response: {}".format(req_msg))
|
||||
|
||||
return themoviedb_json
|
||||
return themoviedb_json
|
||||
|
||||
|
||||
class CustomFormatter(Formatter):
|
||||
def convert_field(self, value, conversion):
|
||||
if conversion is None:
|
||||
return value
|
||||
elif conversion == 's':
|
||||
return str(value)
|
||||
elif conversion == 'r':
|
||||
return repr(value)
|
||||
elif conversion == 'u': # uppercase
|
||||
return str(value).upper()
|
||||
elif conversion == 'l': # lowercase
|
||||
return str(value).lower()
|
||||
elif conversion == 'c': # capitalize
|
||||
return str(value).title()
|
||||
else:
|
||||
return value
|
||||
|
||||
def format_field(self, value, format_spec):
|
||||
if format_spec.startswith('[') and format_spec.endswith(']'):
|
||||
pattern = re.compile(r'\[(\d*):?(\d*)\]')
|
||||
if re.match(pattern, format_spec): # slice
|
||||
items = [x.strip() for x in str(value).split(',')]
|
||||
slice_start, slice_end = re.search(pattern, format_spec).groups()
|
||||
slice_start = max(int(slice_start), 0) if slice_start else None
|
||||
slice_end = min(int(slice_end), len(items)) if slice_end else None
|
||||
return ', '.join(items[slice_start:slice_end])
|
||||
else:
|
||||
return value
|
||||
else:
|
||||
return super(CustomFormatter, self).format_field(value, format_spec)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue