mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-14 01:02:59 -07:00
Add selectize input for email for newsletters
This commit is contained in:
parent
5ac5b3cd29
commit
a13d93f239
2 changed files with 94 additions and 26 deletions
|
@ -1,10 +1,14 @@
|
|||
% if newsletter:
|
||||
<%!
|
||||
from plexpy import helpers, notifiers
|
||||
import json
|
||||
from plexpy import helpers, notifiers, users
|
||||
|
||||
email_notifiers = [n for n in notifiers.get_notifiers() if n['agent_name'] == 'email']
|
||||
sorted(email_notifiers, key=lambda k: (k['agent_label'], k['friendly_name'], k['id']))
|
||||
email_notifiers = [{'id': 0, 'agent_label': 'New Email Configuration', 'friendly_name': ''}] + email_notifiers
|
||||
|
||||
user_emails = [{'user': u['friendly_name'] or u['username'], 'email': u['email']} for u in users.Users().get_users() if u['email']]
|
||||
sorted(user_emails, key=lambda u: u['user'])
|
||||
%>
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
|
@ -56,7 +60,7 @@
|
|||
<div class="form-group">
|
||||
<label for="${item['name']}">${item['label']}</label>
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div class="col-md-12">
|
||||
<input type="${item['input_type']}" class="form-control" id="${item['name']}" name="${item['name']}" value="${item['value']}" size="30" ${'readonly' if item.get('readonly') else ''}>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -76,7 +80,7 @@
|
|||
<div class="form-group">
|
||||
<label for="${item['name']}">${item['label']}</label>
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div class="col-md-12">
|
||||
<input type="button" class="btn btn-bright" id="${item['name']}" name="${item['name']}" value="${item['value']}">
|
||||
</div>
|
||||
</div>
|
||||
|
@ -94,7 +98,7 @@
|
|||
<div class="form-group">
|
||||
<label for="${item['name']}">${item['label']}</label>
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div class="col-md-12">
|
||||
<select class="form-control" id="${item['name']}" name="${item['name']}">
|
||||
% for key, value in sorted(item['select_options'].iteritems()):
|
||||
% if key == item['value']:
|
||||
|
@ -115,7 +119,7 @@
|
|||
<div class="form-group">
|
||||
<label for="friendly_name">Description</label>
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div class="col-md-12">
|
||||
<input type="text" class="form-control" id="friendly_name" name="friendly_name" value="${newsletter['friendly_name']}" size="30">
|
||||
</div>
|
||||
</div>
|
||||
|
@ -130,7 +134,7 @@
|
|||
<div class="form-group">
|
||||
<label for="email_notifier">Email Notification Agent</label>
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div class="col-md-12">
|
||||
<select class="form-control" id="email_notifier" name="email_notifier">
|
||||
% for notifier in email_notifiers:
|
||||
<% selected = 'selected' if notifier['id'] == newsletter['email_config']['notifier'] else '' %>
|
||||
|
@ -145,19 +149,19 @@
|
|||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<p class="help-block">Use an exisiting Email notification agent or enter a new configuration below.</p>
|
||||
<p class="help-block">Use an existing Email notification agent or enter a new configuration below.</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="email_subject">Email Subject</label>
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div class="col-md-12">
|
||||
<input type="text" class="form-control" id="email_subject" name="email_subject" value="${newsletter['email_config']['subject']}" size="30">
|
||||
</div>
|
||||
</div>
|
||||
<p class="help-block">
|
||||
Optional: Enter a subject line for the email. Leave blank for default.
|
||||
<br>
|
||||
Note: You may include <span class="inline-pre">{start_date}</span> and <span class="inline-pre">{end_date}</span> as parameters. The global date format under Settings > General will be used.
|
||||
Note: You may include <span class="inline-pre">{server_name}</span>, <span class="inline-pre">{start_date}</span>, and <span class="inline-pre">{end_date}</span> as parameters. The global date format under Settings > General will be used.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -172,7 +176,7 @@
|
|||
<div class="form-group">
|
||||
<label for="${item['name']}">${item['label']}</label>
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div class="col-md-12">
|
||||
<input type="${item['input_type']}" class="form-control" id="${item['name']}" name="${item['name']}" value="${item['value']}" size="30" ${'readonly' if item.get('readonly') else ''}>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -192,7 +196,7 @@
|
|||
<div class="form-group">
|
||||
<label for="${item['name']}">${item['label']}</label>
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div class="col-md-12">
|
||||
<input type="button" class="btn btn-bright" id="${item['name']}" name="${item['name']}" value="${item['value']}">
|
||||
</div>
|
||||
</div>
|
||||
|
@ -210,7 +214,7 @@
|
|||
<div class="form-group">
|
||||
<label for="${item['name']}">${item['label']}</label>
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div class="col-md-12">
|
||||
<select class="form-control" id="${item['name']}" name="${item['name']}">
|
||||
% for key, value in sorted(item['select_options'].iteritems()):
|
||||
% if key == item['value']:
|
||||
|
@ -237,7 +241,7 @@
|
|||
</p>
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div class="col-md-12">
|
||||
<input type="button" class="btn btn-bright" id="preview_newsletter" name="preview_newsletter" value="Preview ${newsletter['agent_label']} Newsletter">
|
||||
</div>
|
||||
</div>
|
||||
|
@ -248,7 +252,7 @@
|
|||
</p>
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div class="col-md-12">
|
||||
<input type="button" class="btn btn-bright" id="test_newsletter" name="test_newsletter" value="Test ${newsletter['agent_label']} Newsletter">
|
||||
</div>
|
||||
</div>
|
||||
|
@ -284,7 +288,7 @@
|
|||
maxItems: null
|
||||
});
|
||||
var incl_libraries = $incl_libraries[0].selectize;
|
||||
incl_libraries.setValue(${next((c['value'] for c in newsletter['config_options'] if c['name'] == 'recently_added_incl_libraries'), []) | n});
|
||||
incl_libraries.setValue(${json.dumps(next((c['value'] for c in newsletter['config_options'] if c['name'] == 'recently_added_incl_libraries'), [])) | n});
|
||||
|
||||
$('#email_notifier').change(function () {
|
||||
if ($(this).val() === "0") {
|
||||
|
@ -294,6 +298,69 @@
|
|||
}
|
||||
});
|
||||
|
||||
var REGEX_EMAIL = '([a-z0-9!#$%&\'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&\'*+/=?^_`{|}~-]+)*@' +
|
||||
'(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)';
|
||||
var $email_selectors = $('#email_to, #email_cc, #email_bcc').selectize({
|
||||
plugins: ['remove_button'],
|
||||
persist: false,
|
||||
maxItems: null,
|
||||
valueField: 'email',
|
||||
labelField: 'user',
|
||||
searchField: ['user', 'email'],
|
||||
options: ${json.dumps(user_emails) | n},
|
||||
render: {
|
||||
item: function(item, escape) {
|
||||
return '<div>' +
|
||||
(item.user ? '<span class="user">' + escape(item.user) + '</span>' : '') +
|
||||
(item.email ? '<span class="email">' + escape(item.email) + '</span>' : '') +
|
||||
'</div>';
|
||||
},
|
||||
option: function(item, escape) {
|
||||
var label = item.user || item.email;
|
||||
var caption = item.user ? item.email : null;
|
||||
return '<div>' +
|
||||
escape(label) +
|
||||
(caption ? '<span class="caption">' + escape(caption) + '</span>' : '') +
|
||||
'</div>';
|
||||
}
|
||||
},
|
||||
createFilter: function(input) {
|
||||
var match, regex;
|
||||
|
||||
// email@address.com
|
||||
regex = new RegExp('^' + REGEX_EMAIL + '$', 'i');
|
||||
match = input.match(regex);
|
||||
if (match) return !this.options.hasOwnProperty(match[0]);
|
||||
|
||||
// user <email@address.com>
|
||||
regex = new RegExp('^([^<]*)\<' + REGEX_EMAIL + '\>$', 'i');
|
||||
match = input.match(regex);
|
||||
if (match) return !this.options.hasOwnProperty(match[2]);
|
||||
|
||||
return false;
|
||||
},
|
||||
create: function(input) {
|
||||
if ((new RegExp('^' + REGEX_EMAIL + '$', 'i')).test(input)) {
|
||||
return {email: input};
|
||||
}
|
||||
var match = input.match(new RegExp('^([^<]*)\<' + REGEX_EMAIL + '\>$', 'i'));
|
||||
if (match) {
|
||||
return {
|
||||
email : match[2],
|
||||
user : $.trim(match[1])
|
||||
};
|
||||
}
|
||||
alert('Invalid email address.');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
var email_to = $email_selectors[0].selectize;
|
||||
var email_cc = $email_selectors[1].selectize;
|
||||
var email_bcc = $email_selectors[2].selectize;
|
||||
email_to.setValue(${json.dumps(next((c['value'] for c in newsletter['email_config_options'] if c['name'] == 'email_to'), [])) | n});
|
||||
email_cc.setValue(${json.dumps(next((c['value'] for c in newsletter['email_config_options'] if c['name'] == 'email_cc'), [])) | n});
|
||||
email_bcc.setValue(${json.dumps(next((c['value'] for c in newsletter['email_config_options'] if c['name'] == 'email_bcc'), [])) | n});
|
||||
|
||||
function reloadModal() {
|
||||
$.ajax({
|
||||
url: 'get_newsletter_config_modal',
|
||||
|
|
|
@ -238,17 +238,18 @@ def serve_template(templatename, **kwargs):
|
|||
class Newsletter(object):
|
||||
NAME = ''
|
||||
_DEFAULT_CONFIG = {}
|
||||
_DEFAULT_EMAIL_CONFIG = EMAIL().return_default_config()
|
||||
_DEFAULT_EMAIL_CONFIG['from_name'] = 'Tautulli Newsletter'
|
||||
_DEFAULT_EMAIL_CONFIG['notifier'] = 0
|
||||
_DEFAULT_EMAIL_CONFIG['subject'] = 'Tautulli Newsletter'
|
||||
_TEMPLATE = ''
|
||||
|
||||
def __init__(self, config=None, email_config=None):
|
||||
self._default_email_config = EMAIL().return_default_config()
|
||||
self._default_email_config['from_name'] = 'Tautulli Newsletter'
|
||||
self._default_email_config['notifier'] = 0
|
||||
self._default_email_config['subject'] = 'Tautulli Newsletter'
|
||||
|
||||
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.email_config = self.set_config(config=email_config, default=self._DEFAULT_EMAIL_CONFIG)
|
||||
|
||||
self.parameters = {}
|
||||
self.parameters = {'server_name': plexpy.CONFIG.PMS_NAME}
|
||||
self.is_preview = False
|
||||
|
||||
def set_config(self, config=None, default=None):
|
||||
return self._validate_config(config=config, default=default)
|
||||
|
@ -346,7 +347,7 @@ class RecentlyAdded(Newsletter):
|
|||
elif not isinstance(self.config['incl_libraries'], list):
|
||||
self.config['incl_libraries'] = [self.config['incl_libraries']]
|
||||
|
||||
self._default_email_config['subject'] = 'Recently Added to Plex! ({end_date})'
|
||||
self._DEFAULT_EMAIL_CONFIG['subject'] = 'Recently Added to Plex! ({end_date})'
|
||||
|
||||
date_format = helpers.momentjs_to_arrow(plexpy.CONFIG.DATE_FORMAT)
|
||||
|
||||
|
@ -355,8 +356,8 @@ class RecentlyAdded(Newsletter):
|
|||
self.end_date = arrow.get(self.end_time).format(date_format)
|
||||
self.start_date = arrow.get(self.start_time).format(date_format)
|
||||
|
||||
self.parameters = {'start_date': self.start_date,
|
||||
'end_date': self.end_date}
|
||||
self.parameters['start_date'] = self.start_date
|
||||
self.parameters['end_date'] = self.end_date
|
||||
|
||||
self.plexpy_config = {
|
||||
'pms_identifier': plexpy.CONFIG.PMS_IDENTIFIER,
|
||||
|
@ -515,7 +516,7 @@ class RecentlyAdded(Newsletter):
|
|||
'input_type': 'number'
|
||||
},
|
||||
{'label': 'Included Libraries',
|
||||
'value': json.dumps(self.config['incl_libraries']),
|
||||
'value': self.config['incl_libraries'],
|
||||
'description': 'Select the libraries to include in the newsletter.',
|
||||
'name': 'recently_added_incl_libraries',
|
||||
'input_type': 'select',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue