Separate newsletter message and body text

This commit is contained in:
JonnyWong16 2018-04-02 11:12:37 -07:00
parent c260543586
commit 77ed94bbef
7 changed files with 115 additions and 72 deletions

View file

@ -19,8 +19,8 @@
<div class="row">
<ul class="nav nav-tabs list-unstyled" role="tablist">
<li role="presentation" class="active"><a href="#tabs-newsletter_config" aria-controls="tabs-newsletter_config" role="tab" data-toggle="tab">Configuration</a></li>
<li role="presentation"><a href="#tabs-newsletter_text" aria-controls="tabs-newsletter_text" role="tab" data-toggle="tab">Newsletter Text</a></li>
<li role="presentation"><a href="#tabs-newsletter_agent" aria-controls="tabs-newsletter_agent" role="tab" data-toggle="tab">Notification Agent</a></li>
<li role="presentation"><a href="#tabs-newsletter_text" aria-controls="tabs-newsletter_text" role="tab" data-toggle="tab">Newsletter Text</a></li>
<li role="presentation"><a href="#tabs-test_newsletter" aria-controls="tabs-test_newsletter" role="tab" data-toggle="tab">Test Newsletter</a></li>
</ul>
</div>
@ -41,7 +41,7 @@
<div class="col-md-12">
<div id="cron-widget"></div>
<input type="text" id="cron_value" name="cron" value="${newsletter['cron']}" />
<input type="hidden" id="cron_type" name="cron_type" value="${newsletter['cron_type']}" />
<input type="hidden" id="custom_cron" name="newsletter_config_custom_cron" value="${newsletter['config']['custom_cron']}" />
</div>
</div>
<p class="help-block">Set the schedule for the newsletter</p>
@ -155,43 +155,6 @@
</div>
</div>
</div>
<div role="tabpanel" class="tab-pane" id="tabs-newsletter_text">
<label>Newsletter Text</label>
<p class="help-block">
Set the custom formatted text for each type of notification.
<a href="#newsletter-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>
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label for="subject">Subject</label>
<div class="row">
<div class="col-md-12">
<input type="text" class="form-control" id="subject" name="subject" value="${newsletter['subject']}" size="30">
</div>
</div>
<p class="help-block">
Enter a custom subject line for the newsletter. Leave blank for default.
</p>
</div>
<div class="form-group">
<label for="body">Body</label>
<div class="row">
<div class="col-md-12">
<textarea class="form-control" id="body" name="body" value="${newsletter['body']}" data-autoresize>${newsletter['body']}</textarea>
</div>
</div>
<p class="help-block">
Enter a custom body line for the newsletter.
</p>
</div>
</div>
</div>
</div>
<div role="tabpanel" class="tab-pane" id="tabs-newsletter_agent">
<div class="row">
<div class="col-md-12">
@ -342,6 +305,54 @@
</div>
</div>
</div>
<div role="tabpanel" class="tab-pane" id="tabs-newsletter_text">
<label>Newsletter Text</label>
<p class="help-block">
Set the custom formatted text for each type of notification.
<a href="#newsletter-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>
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label for="subject">Subject</label>
<div class="row">
<div class="col-md-12">
<input type="text" class="form-control" id="subject" name="subject" value="${newsletter['subject']}" size="30">
</div>
</div>
<p class="help-block">
Enter a custom subject line for the newsletter. Leave blank for default.
</p>
</div>
<div class="form-group" id="newsletter_body">
<label for="body">Body</label>
<div class="row">
<div class="col-md-12">
<textarea class="form-control" id="body" name="body" data-autoresize>${newsletter['body']}</textarea>
</div>
</div>
<p class="help-block">
Enter a custom body line for the newsletter notification. Leave blank for default.
</p>
</div>
<div class="form-group">
<label for="message">Message</label>
<div class="row">
<div class="col-md-12">
<textarea class="form-control" id="message" name="message" data-autoresize>${newsletter['message']}</textarea>
</div>
</div>
<p class="help-block">
Enter a custom message to include on the newsletter.
</p>
</div>
</div>
</div>
</div>
<div role="tabpanel" class="tab-pane" id="tabs-test_newsletter">
<label>Preview Newsletter</label>
<p class="help-block">
@ -392,24 +403,21 @@
'custom crontab' : 'custom'
},
onChange: function() {
var cron_type = $(this).find('select[name=cron-period]').val();
if(cron_type == 'custom') {
$('#cron_type').val(cron_type);
var cron_period = $(this).find('select[name=cron-period]').val();
$('#custom_cron').val(cron_period === 'custom' ? 1 : 0);
if(cron_period === 'custom') {
$("#cron_value").show();
} else {
$('#cron_type').val('widget');
$("#cron_value").hide().val($(this).cron('value'));
}
}
});
if ('${newsletter['cron_type']}' === 'custom') {
if (${newsletter['config']['custom_cron']}) {
$('#cron-widget').find('select[name=cron-period]').val('custom');
$('#cron_type').val('${newsletter['cron_type']}');
$("#cron_value").val('${newsletter['cron']}').show();
$('#cron_value').val('${newsletter['cron']}').show();
} else {
$('#cron_type').val('${newsletter['cron_type']}');
$("#cron_value").hide();
$('#cron_value').hide();
cron_widget.cron('value', '${newsletter['cron']}');
}
@ -444,10 +452,12 @@
function toggleEmailSelect () {
if ($('#newsletter_config_formatted_checkbox').is(':checked')) {
$('#newsletter_body').hide();
$('#email_notifier_select').show();
$('#other_notifier_select').hide();
toggleNewEmailConfig();
} else {
$('#newsletter_body').show();
$('#email_notifier_select').hide();
$('#other_notifier_select').show();
$('#newsletter-email-config').hide();

View file

@ -626,11 +626,11 @@
</td>
</tr>
% if body:
% if message:
<tr>
<td class="wrapper" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 14px;vertical-align: top;box-sizing: border-box;padding: 5px;overflow: auto;">
<div class="sub-header-bar" style="margin-left: auto;margin-right: auto;font-size: 30px;text-align: center;width: 200px;border-top: 1px solid #E5A00D;margin-top: 15px;margin-bottom: 25px;"></div>
<div class="body-message" style="font-size: 20px;text-align: center;width: 80%;margin-left: auto;margin-right: auto;">${'<br>'.join(l for l in body.splitlines()) | n}</div>
<div class="body-message" style="font-size: 20px;text-align: center;width: 80%;margin-left: auto;margin-right: auto;">${'<br>'.join(l for l in message.splitlines()) | n}</div>
</td>
</tr>
% endif

View file

@ -626,11 +626,11 @@
</td>
</tr>
% if body:
% if message:
<tr>
<td class="wrapper">
<div class="sub-header-bar"></div>
<div class="body-message">${'<br>'.join(l for l in body.splitlines()) | n}</div>
<div class="body-message">${'<br>'.join(l for l in message.splitlines()) | n}</div>
</td>
</tr>
% endif

View file

@ -639,14 +639,15 @@ def dbcheck():
'CREATE TABLE IF NOT EXISTS newsletters (id INTEGER PRIMARY KEY AUTOINCREMENT, '
'agent_id INTEGER, agent_name TEXT, agent_label TEXT, '
'friendly_name TEXT, newsletter_config TEXT, email_config TEXT, '
'subject TEXT, body TEXT, cron TEXT NOT NULL DEFAULT "0 0 * * 0", cron_type TEXT, active INTEGER DEFAULT 0)'
'subject TEXT, body TEXT, message TEXT, '
'cron TEXT NOT NULL DEFAULT "0 0 * * 0", active INTEGER DEFAULT 0)'
)
# newsletter_log table :: This is a table which logs newsletters sent
c_db.execute(
'CREATE TABLE IF NOT EXISTS newsletter_log (id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp INTEGER, '
'newsletter_id INTEGER, agent_id INTEGER, agent_name TEXT, notify_action TEXT, '
'subject_text TEXT, body_text TEXT, start_date TEXT, end_date TEXT, '
'subject_text TEXT, body_text TEXT, message_text TEXT, start_date TEXT, end_date TEXT, '
'uuid TEXT UNIQUE, success INTEGER DEFAULT 0)'
)

View file

@ -80,21 +80,26 @@ def notify(newsletter_id=None, notify_action=None, **kwargs):
if notify_action in ('test', 'api'):
subject = kwargs.pop('subject', None) or newsletter_config['subject']
body = kwargs.pop('body', None) or newsletter_config['body']
message = kwargs.pop('message', None) or newsletter_config['message']
else:
subject = newsletter_config['subject']
body = newsletter_config['body']
message = newsletter_config['message']
newsletter_agent = newsletters.get_agent_class(agent_id=newsletter_config['agent_id'],
config=newsletter_config['config'],
email_config=newsletter_config['email_config'],
subject=subject,
body=body)
body=body,
message=message
)
# Set the newsletter state in the db
newsletter_log_id = set_notify_state(newsletter=newsletter_config,
notify_action=notify_action,
subject=newsletter_agent.subject_formatted,
body=newsletter_agent.body_formatted,
message=newsletter_agent.message_formatted,
start_date=newsletter_agent.start_date.format('YYYY-MM-DD'),
end_date=newsletter_agent.end_date.format('YYYY-MM-DD'),
newsletter_uuid=newsletter_agent.uuid)
@ -107,7 +112,7 @@ def notify(newsletter_id=None, notify_action=None, **kwargs):
return True
def set_notify_state(newsletter, notify_action, subject, body, start_date, end_date, newsletter_uuid):
def set_notify_state(newsletter, notify_action, subject, body, message, start_date, end_date, newsletter_uuid):
if newsletter and notify_action:
db = database.MonitorDatabase()
@ -121,6 +126,7 @@ def set_notify_state(newsletter, notify_action, subject, body, start_date, end_d
'notify_action': notify_action,
'subject_text': subject,
'body_text': body,
'message_text': message,
'start_date': start_date,
'end_date': end_date}

View file

@ -54,6 +54,7 @@ def available_notification_actions():
'description': 'Trigger a notification on a certain schedule.',
'subject': 'Tautulli Newsletter',
'body': 'Tautulli Newsletter',
'message': '',
'icon': 'fa-calendar',
'media_types': ('newsletter',)
}
@ -63,7 +64,7 @@ def available_notification_actions():
def get_agent_class(agent_id=None, config=None, email_config=None, start_date=None, end_date=None,
subject=None, body=None):
subject=None, body=None, message=None):
if str(agent_id).isdigit():
agent_id = int(agent_id)
@ -72,7 +73,8 @@ def get_agent_class(agent_id=None, config=None, email_config=None, start_date=No
'start_date': start_date,
'end_date': end_date,
'subject': subject,
'body': body}
'body': body,
'message': message}
if agent_id == 0:
return RecentlyAdded(**kwargs)
@ -135,14 +137,16 @@ def get_newsletter_config(newsletter_id=None):
email_config = json.loads(result.pop('email_config', '{}'))
subject = result.pop('subject')
body = result.pop('body')
message = result.pop('message')
newsletter_agent = get_agent_class(agent_id=result['agent_id'], config=config, email_config=email_config,
subject=subject, body=body)
subject=subject, body=body, message=message)
except Exception as e:
logger.error(u"Tautulli Newsletters :: Failed to get newsletter config options: %s." % e)
return
result['subject'] = newsletter_agent.subject
result['body'] = newsletter_agent.body
result['message'] = newsletter_agent.message
result['config'] = newsletter_agent.config
result['email_config'] = newsletter_agent.email_config
result['config_options'] = newsletter_agent.return_config_options()
@ -176,7 +180,8 @@ def add_newsletter_config(agent_id=None, **kwargs):
'newsletter_config': json.dumps(agent_class.config),
'email_config': json.dumps(agent_class.email_config),
'subject': agent_class.subject,
'body': agent_class.body
'body': agent_class.body,
'message': agent_class.message
}
db = database.MonitorDatabase()
@ -216,9 +221,10 @@ def set_newsletter_config(newsletter_id=None, agent_id=None, **kwargs):
subject = kwargs.pop('subject')
body = kwargs.pop('body')
message = kwargs.pop('message')
agent_class = get_agent_class(agent_id=agent['id'], config=newsletter_config, email_config=email_config,
subject=subject, body=body)
subject=subject, body=body, message=message)
keys = {'id': newsletter_id}
values = {'agent_id': agent['id'],
@ -229,8 +235,8 @@ def set_newsletter_config(newsletter_id=None, agent_id=None, **kwargs):
'email_config': json.dumps(agent_class.email_config),
'subject': agent_class.subject,
'body': agent_class.body,
'message': agent_class.message,
'cron': kwargs.get('cron'),
'cron_type': kwargs.get('cron_type'),
'active': kwargs.get('active')
}
@ -246,14 +252,15 @@ def set_newsletter_config(newsletter_id=None, agent_id=None, **kwargs):
return False
def send_newsletter(newsletter_id=None, subject=None, body=None, newsletter_log_id=None, **kwargs):
def send_newsletter(newsletter_id=None, subject=None, body=None, message=None, newsletter_log_id=None, **kwargs):
newsletter_config = get_newsletter_config(newsletter_id=newsletter_id)
if newsletter_config:
agent = get_agent_class(agent_id=newsletter_config['agent_id'],
config=newsletter_config['config'],
email_config=newsletter_config['email_config'],
subject=subject,
body=body)
body=body,
messsage=message)
return agent.send()
else:
logger.debug(u"Tautulli Newsletters :: Notification requested but no newsletter_id received.")
@ -288,18 +295,21 @@ def generate_newsletter_uuid():
class Newsletter(object):
NAME = ''
_DEFAULT_CONFIG = {'last_days': 7,
_DEFAULT_CONFIG = {'custom_cron': 0,
'last_days': 7,
'formatted': 1,
'notifier_id': 0}
_DEFAULT_EMAIL_CONFIG = EMAIL().return_default_config()
_DEFAULT_EMAIL_CONFIG['from_name'] = 'Tautulli Newsletter'
_DEFAULT_EMAIL_CONFIG['notifier_id'] = 0
_DEFAULT_SUBJECT = 'Tautulli Newsletter'
_DEFAULT_BODY = ''
_DEFAULT_BODY = 'View the newsletter here: {newsletter_url}'
_DEFAULT_MESSAGE = ''
_TEMPLATE_MASTER = ''
_TEMPLATE = ''
def __init__(self, config=None, email_config=None, start_date=None, end_date=None, subject=None, body=None):
def __init__(self, config=None, email_config=None, start_date=None, end_date=None,
subject=None, body=None, message=None):
self.config = self.set_config(config=config, default=self._DEFAULT_CONFIG)
self.email_config = self.set_config(config=email_config, default=self._DEFAULT_EMAIL_CONFIG)
self.uuid = generate_newsletter_uuid()
@ -331,7 +341,8 @@ class Newsletter(object):
self.parameters = self.build_params()
self.subject = subject or self._DEFAULT_SUBJECT
self.body = body or self._DEFAULT_BODY
self.subject_formatted, self.body_formatted = self.build_text()
self.message = message or self._DEFAULT_MESSAGE
self.subject_formatted, self.body_formatted, self.message_formatted = self.build_text()
self.data = {}
self.newsletter = None
@ -392,6 +403,7 @@ class Newsletter(object):
uuid=self.uuid,
subject=self.subject_formatted,
body=self.body_formatted,
message=self.message_formatted,
parameters=self.parameters,
data=self.data,
preview=self.is_preview
@ -498,7 +510,18 @@ class Newsletter(object):
u"Tautulli Newsletter :: Unable to parse custom newsletter body: %s. Using fallback." % e)
body = unicode(self._DEFAULT_BODY).format(**self.parameters)
return subject, body
try:
message = custom_formatter.format(unicode(self.message), **self.parameters)
except LookupError as e:
logger.error(
u"Tautulli Newsletter :: Unable to parse parameter %s in newsletter message. Using fallback." % e)
message = unicode(self._DEFAULT_MESSAGE).format(**self.parameters)
except Exception as e:
logger.error(
u"Tautulli Newsletter :: Unable to parse custom newsletter message: %s. Using fallback." % e)
message = unicode(self._DEFAULT_MESSAGE).format(**self.parameters)
return subject, body, message
def return_config_options(self):
return self._return_config_options()
@ -530,7 +553,8 @@ class RecentlyAdded(Newsletter):
_DEFAULT_CONFIG = Newsletter._DEFAULT_CONFIG.copy()
_DEFAULT_CONFIG['incl_libraries'] = []
_DEFAULT_SUBJECT = 'Recently Added to {server_name}! ({end_date})'
_DEFAULT_BODY = ''
_DEFAULT_BODY = 'View the newsletter here: {newsletter_url}'
_DEFAULT_MESSAGE = ''
_TEMPLATE_MASTER = 'recently_added_master.html'
_TEMPLATE = 'recently_added.html'

View file

@ -5564,7 +5564,7 @@ class WebInterface(object):
@cherrypy.tools.json_out()
@requireAuth(member_of("admin"))
@addtoapi("notify_newsletter")
def send_newsletter(self, newsletter_id=None, subject='', body='', notify_action='', **kwargs):
def send_newsletter(self, newsletter_id=None, subject='', body='', message='', notify_action='', **kwargs):
""" Send a newsletter using Tautulli.
```
@ -5591,6 +5591,7 @@ class WebInterface(object):
notify_action=notify_action,
subject=subject,
body=body,
message=message,
**kwargs)
return {'result': 'success', 'message': 'Newsletter queued.'}
else:
@ -5638,7 +5639,8 @@ class WebInterface(object):
start_date=start_date,
end_date=end_date,
subject=newsletter['subject'],
body=newsletter['body'])
body=newsletter['body'],
message=newsletter['message'])
preview = (preview == 'true')
master = (master == 'true')
raw = (raw == 'true')