-
@@ -465,6 +469,70 @@
var osx_notify_app = $('#osx_notify_app').val();
$.get('osxnotifyregister', { 'app': osx_notify_app }, function (data) { showMsg('
' + data, false, true, 3000); });
})
+
+ % elif notifier['agent_name'] == 'email':
+ 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 '
' +
+ (item.user ? '' + escape(item.user) + '' : '') +
+ (item.email ? '' + escape(item.email) + '' : '') +
+ '
';
+ },
+ option: function(item, escape) {
+ var label = item.user || item.email;
+ var caption = item.user ? item.email : null;
+ return '
' +
+ escape(label) +
+ (caption ? '' + escape(caption) + '' : '') +
+ '
';
+ }
+ },
+ 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
+ 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 notifier['config_options'] if c['name'] == 'email_to'), [])) | n});
+ email_cc.setValue(${json.dumps(next((c['value'] for c in notifier['config_options'] if c['name'] == 'email_cc'), [])) | n});
+ email_bcc.setValue(${json.dumps(next((c['value'] for c in notifier['config_options'] if c['name'] == 'email_bcc'), [])) | n});
% endif
function validateLogic() {
diff --git a/plexpy/notifiers.py b/plexpy/notifiers.py
index b1e91a48..5ec858c7 100644
--- a/plexpy/notifiers.py
+++ b/plexpy/notifiers.py
@@ -60,6 +60,7 @@ import logger
import mobile_app
import pmsconnect
import request
+import users
from plexpy.config import _BLACKLIST_KEYS, _WHITELIST_KEYS
@@ -1245,6 +1246,16 @@ class EMAIL(Notifier):
'html_support': 1
}
+ def __init__(self, config=None):
+ super(EMAIL, self).__init__(config=config)
+
+ if not isinstance(self.config['to'], list):
+ self.config['to'] = [x.strip() for x in self.config['to'].split(';')]
+ if not isinstance(self.config['cc'], list):
+ self.config['cc'] = [x.strip() for x in self.config['cc'].split(';')]
+ if not isinstance(self.config['bcc'], list):
+ self.config['bcc'] = [x.strip() for x in self.config['bcc'].split(';')]
+
def notify(self, subject='', body='', action='', **kwargs):
if not subject or not body:
return
@@ -1259,13 +1270,10 @@ class EMAIL(Notifier):
msg['Subject'] = subject
msg['From'] = email.utils.formataddr((self.config['from_name'], self.config['from']))
- msg['To'] = self.config['to']
- msg['CC'] = self.config['cc']
+ msg['To'] = ','.join(self.config['to'])
+ msg['CC'] = ','.join(self.config['cc'])
- recipients = [x.strip() for x in self.config['to'].split(';')] \
- + [x.strip() for x in self.config['cc'].split(';')] \
- + [x.strip() for x in self.config['bcc'].split(';')]
- recipients = filter(None, recipients)
+ recipients = self.config['to'] + self.config['cc'] + self.config['bcc']
try:
mailserver = smtplib.SMTP(self.config['smtp_server'], self.config['smtp_port'])
@@ -1289,6 +1297,8 @@ class EMAIL(Notifier):
return False
def return_config_options(self):
+ user_emails = {} # User selection set with selectize options
+
config_option = [{'label': 'From Name',
'value': self.config['from_name'],
'name': 'email_from_name',
@@ -1304,20 +1314,23 @@ class EMAIL(Notifier):
{'label': 'To',
'value': self.config['to'],
'name': 'email_to',
- 'description': 'The email address(es) of the recipients, separated by semicolons (;).',
- 'input_type': 'text'
+ 'description': 'The email address(es) of the recipients.',
+ 'input_type': 'select',
+ 'select_options': user_emails
},
{'label': 'CC',
'value': self.config['cc'],
'name': 'email_cc',
- 'description': 'The email address(es) to CC, separated by semicolons (;).',
- 'input_type': 'text'
+ 'description': 'The email address(es) to CC.',
+ 'input_type': 'select',
+ 'select_options': user_emails
},
{'label': 'BCC',
'value': self.config['bcc'],
'name': 'email_bcc',
- 'description': 'The email address(es) to BCC, separated by semicolons (;).',
- 'input_type': 'text'
+ 'description': 'The email address(es) to BCC.',
+ 'input_type': 'select',
+ 'select_options': user_emails
},
{'label': 'SMTP Server',
'value': self.config['smtp_server'],
diff --git a/plexpy/users.py b/plexpy/users.py
index 4c79939b..4ba3ee9d 100644
--- a/plexpy/users.py
+++ b/plexpy/users.py
@@ -580,6 +580,27 @@ class Users(object):
return recently_watched
+ def get_users(self):
+ monitor_db = database.MonitorDatabase()
+
+ try:
+ query = 'SELECT user_id, username, friendly_name, email FROM users WHERE deleted_user = 0'
+ result = monitor_db.select(query=query)
+ except Exception as e:
+ logger.warn(u"Tautulli Users :: Unable to execute database query for get_users: %s." % e)
+ return None
+
+ users = []
+ for item in result:
+ user = {'user_id': item['user_id'],
+ 'username': item['username'],
+ 'friendly_name': item['friendly_name'],
+ 'email': item['email']
+ }
+ users.append(user)
+
+ return users
+
def delete_all_history(self, user_id=None):
monitor_db = database.MonitorDatabase()