diff --git a/data/interfaces/default/css/plexpy.css b/data/interfaces/default/css/plexpy.css
index 066f9a37..3ff90a72 100644
--- a/data/interfaces/default/css/plexpy.css
+++ b/data/interfaces/default/css/plexpy.css
@@ -131,19 +131,19 @@ select.form-control:focus,
.react-selectize.root-node.open .react-selectize-control .react-selectize-toggle-button path {
fill: #999 !important;
}
-.selectize-control .selectize-input > div .email {
+.selectize-control .selectize-input > div .item-value {
opacity: 0.8;
font-size: 12px;
}
-.selectize-control .selectize-input > div .user + .email {
+.selectize-control .selectize-input > div .item-text + .item-value {
margin-left: 5px;
}
-.selectize-control .selectize-input > div .email:before {
+.selectize-control .selectize-input > div .item-value:before {
content: '<';
opacity: 0.8;
font-size: 12px;
}
-.selectize-control .selectize-input > div .email:after {
+.selectize-control .selectize-input > div .item-value:after {
content: '>';
opacity: 0.8;
font-size: 12px;
@@ -153,6 +153,25 @@ select.form-control:focus,
display: block;
color: #a0a0a0;
}
+.selectize-control .selectize-dropdown .select-all,
+.selectize-control .selectize-dropdown .remove-all {
+ font-weight: bold;
+}
+.selectize-control .selectize-dropdown .border-all {
+ pointer-events: none;
+ display: block;
+ height: 1px;
+ margin: 9px -12px 9px -12px;
+ padding: 0 !important;
+ overflow: hidden;
+ background-color: #e5e5e5;
+}
+.selectize-control .selectize-dropdown .border-all:last-child {
+ display: none;
+}
+.selectize-dropdown .optgroup-header {
+ font-weight: bold;
+}
select.form-control option {
color: #555;
background-color: #fff;
diff --git a/data/interfaces/default/notifier_config.html b/data/interfaces/default/notifier_config.html
index 53128205..4c5bd81b 100644
--- a/data/interfaces/default/notifier_config.html
+++ b/data/interfaces/default/notifier_config.html
@@ -98,6 +98,33 @@
${item['description'] | n}
+ % elif item['input_type'] == 'selectize':
+
% endif
% endfor
@@ -477,26 +504,37 @@
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 '' +
- (item.user ? '' + escape(item.user) + '' : '') +
- (item.email ? '' + escape(item.email) + '' : '') +
+ (item.text ? '' + escape(item.text) + '' : '') +
+ (item.value ? '' + escape(item.value) + '' : '') +
'
';
},
option: function(item, escape) {
- var label = item.user || item.email;
- var caption = item.user ? item.email : null;
+ var label = item.text || item.value;
+ var caption = item.text ? item.value : null;
+ if (item.value.endsWith('-all')) {
+ return '' + escape(label) + '
'
+ }
return '' +
escape(label) +
(caption ? '' + escape(caption) + '' : '') +
'
';
}
},
+ onItemAdd: function(value) {
+ if (value === 'select-all') {
+ var all_keys = $.map(this.options, function(option){
+ return option.value.endsWith('-all') ? null : option.value;
+ });
+ this.setValue(all_keys);
+ } else if (value === 'remove-all') {
+ this.clear();
+ this.refreshOptions();
+ this.positionDropdown();
+ }
+ },
createFilter: function(input) {
var match, regex;
@@ -514,16 +552,15 @@
},
create: function(input) {
if ((new RegExp('^' + REGEX_EMAIL + '$', 'i')).test(input)) {
- return {email: input};
+ return {value: input};
}
var match = input.match(new RegExp('^([^<]*)\<' + REGEX_EMAIL + '\>$', 'i'));
if (match) {
return {
- email : match[2],
- user : $.trim(match[1])
+ value : match[2],
+ text : $.trim(match[1])
};
}
- alert('Invalid email address.');
return false;
}
});
diff --git a/plexpy/notifiers.py b/plexpy/notifiers.py
index 657e7f18..15e0f278 100644
--- a/plexpy/notifiers.py
+++ b/plexpy/notifiers.py
@@ -1293,8 +1293,28 @@ class EMAIL(Notifier):
logger.error(u"Tautulli Notifiers :: {name} notification failed: {e}".format(name=self.NAME, e=e))
return False
+ def get_user_emails(self):
+ emails = {u['email']: u['friendly_name'] for u in users.Users().get_users() if u['email']}
+
+ user_emails_to = {v: '' for v in self.config['to']}
+ user_emails_cc = {v: '' for v in self.config['cc']}
+ user_emails_bcc = {v: '' for v in self.config['bcc']}
+
+ user_emails_to.update(emails)
+ user_emails_cc.update(emails)
+ user_emails_bcc.update(emails)
+
+ user_emails_to = [{'value': k, 'text': v}
+ for k, v in sorted(user_emails_to.iteritems(), key=lambda x: x[1].lower())]
+ user_emails_cc = [{'value': k, 'text': v}
+ for k, v in sorted(user_emails_cc.iteritems(), key=lambda x: x[1].lower())]
+ user_emails_bcc = [{'value': k, 'text': v}
+ for k, v in sorted(user_emails_bcc.iteritems(), key=lambda x: x[1].lower())]
+
+ return user_emails_to, user_emails_cc, user_emails_bcc
+
def return_config_options(self):
- user_emails = {} # User selection set with selectize options
+ user_emails_to, user_emails_cc, user_emails_bcc = self.get_user_emails()
config_option = [{'label': 'From Name',
'value': self.config['from_name'],
@@ -1312,22 +1332,22 @@ class EMAIL(Notifier):
'value': self.config['to'],
'name': 'email_to',
'description': 'The email address(es) of the recipients.',
- 'input_type': 'select',
- 'select_options': user_emails
+ 'input_type': 'selectize',
+ 'select_options': user_emails_to
},
{'label': 'CC',
'value': self.config['cc'],
'name': 'email_cc',
'description': 'The email address(es) to CC.',
- 'input_type': 'select',
- 'select_options': user_emails
+ 'input_type': 'selectize',
+ 'select_options': user_emails_cc
},
{'label': 'BCC',
'value': self.config['bcc'],
'name': 'email_bcc',
'description': 'The email address(es) to BCC.',
- 'input_type': 'select',
- 'select_options': user_emails
+ 'input_type': 'selectize',
+ 'select_options': user_emails_bcc
},
{'label': 'SMTP Server',
'value': self.config['smtp_server'],
diff --git a/plexpy/users.py b/plexpy/users.py
index 6bbab6b7..08b9f254 100644
--- a/plexpy/users.py
+++ b/plexpy/users.py
@@ -597,7 +597,7 @@ class Users(object):
for item in result:
user = {'user_id': item['user_id'],
'username': item['username'],
- 'friendly_name': item['friendly_name'],
+ 'friendly_name': item['friendly_name'] or item['username'],
'email': item['email']
}
users.append(user)