mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-10 23:42:37 -07:00
Change to include libraries instead of exclude
This commit is contained in:
parent
d1f982847b
commit
32645c374e
7 changed files with 62 additions and 134 deletions
|
@ -125,8 +125,10 @@ div.form-control .selectize-input {
|
||||||
padding-bottom: 2px !important;
|
padding-bottom: 2px !important;
|
||||||
transition: background-color .3s;
|
transition: background-color .3s;
|
||||||
}
|
}
|
||||||
.react-selectize.root-node .simple-value span {
|
.react-selectize.root-node .simple-value span,
|
||||||
|
.selectize-control.multi .selectize-input > div {
|
||||||
padding-bottom: 2px !important;
|
padding-bottom: 2px !important;
|
||||||
|
padding-left: 5px !important;
|
||||||
}
|
}
|
||||||
.react-selectize.root-node .react-selectize-control .react-selectize-search-field-and-selected-values .value-wrapper:not(:first-child):before {
|
.react-selectize.root-node .react-selectize-control .react-selectize-search-field-and-selected-values .value-wrapper:not(:first-child):before {
|
||||||
content: "or";
|
content: "or";
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
<%!
|
|
||||||
from plexpy import helpers
|
|
||||||
%>
|
|
||||||
% if newsletter:
|
% if newsletter:
|
||||||
|
<%!
|
||||||
|
from plexpy import helpers, notifiers
|
||||||
|
|
||||||
|
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
|
||||||
|
%>
|
||||||
<div class="modal-dialog" role="document">
|
<div class="modal-dialog" role="document">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
|
@ -91,7 +95,7 @@
|
||||||
<label for="${item['name']}">${item['label']}</label>
|
<label for="${item['name']}">${item['label']}</label>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-8">
|
<div class="col-md-8">
|
||||||
<select class="form-control" id="${item['name']}" name="${item['name']}" ${'multiple' if item.get('multiple') else ''}>
|
<select class="form-control" id="${item['name']}" name="${item['name']}">
|
||||||
% for key, value in sorted(item['select_options'].iteritems()):
|
% for key, value in sorted(item['select_options'].iteritems()):
|
||||||
% if key == item['value']:
|
% if key == item['value']:
|
||||||
<option value="${key}" selected>${value}</option>
|
<option value="${key}" selected>${value}</option>
|
||||||
|
@ -128,14 +132,14 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-8">
|
<div class="col-md-8">
|
||||||
<select class="form-control" id="email_notifier" name="email_notifier">
|
<select class="form-control" id="email_notifier" name="email_notifier">
|
||||||
% for item in newsletter['email_notifiers']:
|
% for notifier in email_notifiers:
|
||||||
<% selected = 'selected' if item['id'] == newsletter['email_notifier'] else '' %>
|
<% selected = 'selected' if notifier['id'] == newsletter['email_notifier'] else '' %>
|
||||||
% if item['friendly_name']:
|
% if notifier['friendly_name']:
|
||||||
<option value="${item['id']}" ${selected}>${item['agent_label']} (${item['id']} - ${item['friendly_name']})</option>
|
<option value="${notifier['id']}" ${selected}>${notifier['agent_label']} (${notifier['id']} - ${notifier['friendly_name']})</option>
|
||||||
% elif item['id']:
|
% elif notifier['id']:
|
||||||
<option value="${item['id']}" ${selected}>${item['agent_label']} (${item['id']})</option>
|
<option value="${notifier['id']}" ${selected}>${notifier['agent_label']} (${notifier['id']})</option>
|
||||||
% else:
|
% else:
|
||||||
<option value="${item['id']}" ${selected}>${item['agent_label']}</option>
|
<option value="${notifier['id']}" ${selected}>${notifier['agent_label']}</option>
|
||||||
% endif
|
% endif
|
||||||
% endfor
|
% endfor
|
||||||
</select>
|
</select>
|
||||||
|
@ -262,12 +266,12 @@
|
||||||
}
|
}
|
||||||
}); // apply cron with default options
|
}); // apply cron with default options
|
||||||
|
|
||||||
var $excl_libraries = $('#recently_added_excl_libraries').selectize({
|
var $incl_libraries = $('#recently_added_incl_libraries').selectize({
|
||||||
plugins: ['remove_button'],
|
plugins: ['remove_button'],
|
||||||
maxItems: null
|
maxItems: null
|
||||||
});
|
});
|
||||||
var excl_libraries = $excl_libraries[0].selectize;
|
var incl_libraries = $incl_libraries[0].selectize;
|
||||||
excl_libraries.setValue(${next((c['value'] for c in newsletter['config_options'] if c['name'] == 'recently_added_excl_libraries'), []) | n});
|
incl_libraries.setValue(${next((c['value'] for c in newsletter['config_options'] if c['name'] == 'recently_added_incl_libraries'), []) | n});
|
||||||
|
|
||||||
$('#email_notifier').change(function () {
|
$('#email_notifier').change(function () {
|
||||||
if ($(this).val() === "0") {
|
if ($(this).val() === "0") {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
% if notifier:
|
||||||
<%!
|
<%!
|
||||||
import json
|
import json
|
||||||
from plexpy import helpers, notifiers, users
|
from plexpy import helpers, notifiers, users
|
||||||
|
@ -6,7 +7,6 @@
|
||||||
user_emails = [{'user': u['friendly_name'] or u['username'], 'email': u['email']} for u in users.Users().get_users() if u['email']]
|
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'])
|
sorted(user_emails, key=lambda u: u['user'])
|
||||||
%>
|
%>
|
||||||
% if notifier:
|
|
||||||
<div class="modal-dialog" role="document">
|
<div class="modal-dialog" role="document">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
% if recently_added:
|
<!doctype html>
|
||||||
<!doctype html>
|
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta name="viewport" content="width=device-width"/>
|
<meta name="viewport" content="width=device-width"/>
|
||||||
|
@ -1036,4 +1035,3 @@
|
||||||
</table>
|
</table>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
% endif
|
|
|
@ -911,7 +911,7 @@ class Libraries(object):
|
||||||
monitor_db = database.MonitorDatabase()
|
monitor_db = database.MonitorDatabase()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
query = 'SELECT section_id, section_name FROM library_sections WHERE deleted_section = 0'
|
query = 'SELECT section_id, section_name, section_type FROM library_sections WHERE deleted_section = 0'
|
||||||
result = monitor_db.select(query=query)
|
result = monitor_db.select(query=query)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warn(u"Tautulli Libraries :: Unable to execute database query for get_sections: %s." % e)
|
logger.warn(u"Tautulli Libraries :: Unable to execute database query for get_sections: %s." % e)
|
||||||
|
@ -920,7 +920,8 @@ class Libraries(object):
|
||||||
libraries = []
|
libraries = []
|
||||||
for item in result:
|
for item in result:
|
||||||
library = {'section_id': item['section_id'],
|
library = {'section_id': item['section_id'],
|
||||||
'section_name': item['section_name']
|
'section_name': item['section_name'],
|
||||||
|
'section_type': item['section_type']
|
||||||
}
|
}
|
||||||
libraries.append(library)
|
libraries.append(library)
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ import logger
|
||||||
import notification_handler
|
import notification_handler
|
||||||
import pmsconnect
|
import pmsconnect
|
||||||
import request
|
import request
|
||||||
from notifiers import get_notifiers, EMAIL
|
from notifiers import EMAIL
|
||||||
|
|
||||||
|
|
||||||
AGENT_IDS = {
|
AGENT_IDS = {
|
||||||
|
@ -123,21 +123,9 @@ def get_newsletter_config(newsletter_id=None):
|
||||||
logger.error(u"Tautulli Newsletters :: Failed to get newsletter config options: %s." % e)
|
logger.error(u"Tautulli Newsletters :: Failed to get newsletter config options: %s." % e)
|
||||||
return
|
return
|
||||||
|
|
||||||
notifiers = []
|
|
||||||
for n in get_notifiers():
|
|
||||||
if n['agent_name'] == 'email':
|
|
||||||
notifiers.append({
|
|
||||||
'id': n['id'],
|
|
||||||
'agent_label': n['agent_label'],
|
|
||||||
'friendly_name': n['friendly_name']
|
|
||||||
})
|
|
||||||
sorted(notifiers, key=lambda k: (k['agent_label'], k['friendly_name'], k['id']))
|
|
||||||
email_notifiers = [{'id': 0, 'agent_label': 'New Email Configuration', 'friendly_name': ''}] + notifiers
|
|
||||||
|
|
||||||
result['config'] = config
|
result['config'] = config
|
||||||
result['config_options'] = newsletter_config
|
result['config_options'] = newsletter_config
|
||||||
result['email_config_options'] = newsletter_email_config
|
result['email_config_options'] = newsletter_email_config
|
||||||
result['email_notifiers'] = email_notifiers
|
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@ -321,13 +309,18 @@ class RecentlyAdded(Newsletter):
|
||||||
"""
|
"""
|
||||||
NAME = 'Recently Added'
|
NAME = 'Recently Added'
|
||||||
_DEFAULT_CONFIG = {'last_days': 7,
|
_DEFAULT_CONFIG = {'last_days': 7,
|
||||||
'excl_libraries': ''
|
'incl_libraries': None
|
||||||
}
|
}
|
||||||
_TEMPLATE = 'recently_added.html'
|
_TEMPLATE = 'recently_added.html'
|
||||||
|
|
||||||
def __init__(self, config=None, email_config=None):
|
def __init__(self, config=None, email_config=None):
|
||||||
super(RecentlyAdded, self).__init__(config=config, email_config=email_config)
|
super(RecentlyAdded, self).__init__(config=config, email_config=email_config)
|
||||||
|
|
||||||
|
if self.config['incl_libraries'] is None:
|
||||||
|
self.config['incl_libraries'] = []
|
||||||
|
elif not isinstance(self.config['incl_libraries'], list):
|
||||||
|
self.config['incl_libraries'] = [self.config['incl_libraries']]
|
||||||
|
|
||||||
date_format = helpers.momentjs_to_arrow(plexpy.CONFIG.DATE_FORMAT)
|
date_format = helpers.momentjs_to_arrow(plexpy.CONFIG.DATE_FORMAT)
|
||||||
|
|
||||||
self.end_time = int(time.time())
|
self.end_time = int(time.time())
|
||||||
|
@ -363,8 +356,8 @@ class RecentlyAdded(Newsletter):
|
||||||
if media_type == 'movie':
|
if media_type == 'movie':
|
||||||
movie_list = []
|
movie_list = []
|
||||||
for item in recently_added:
|
for item in recently_added:
|
||||||
# Filter out excluded libraries
|
# Filter included libraries
|
||||||
if item['section_id'] in self.config['excl_libraries']:
|
if item['section_id'] not in self.config['incl_libraries']:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
movie_list.append(item)
|
movie_list.append(item)
|
||||||
|
@ -375,8 +368,8 @@ class RecentlyAdded(Newsletter):
|
||||||
shows_list = []
|
shows_list = []
|
||||||
show_rating_keys = []
|
show_rating_keys = []
|
||||||
for item in recently_added:
|
for item in recently_added:
|
||||||
# Filter out excluded libraries
|
# Filter included libraries
|
||||||
if item['section_id'] in self.config['excl_libraries']:
|
if item['section_id'] not in self.config['incl_libraries']:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if item['media_type'] == 'show':
|
if item['media_type'] == 'show':
|
||||||
|
@ -422,8 +415,8 @@ class RecentlyAdded(Newsletter):
|
||||||
artists_list = []
|
artists_list = []
|
||||||
artist_rating_keys = []
|
artist_rating_keys = []
|
||||||
for item in recently_added:
|
for item in recently_added:
|
||||||
# Filter out excluded libraries
|
# Filter included libraries
|
||||||
if item['section_id'] in self.config['excl_libraries']:
|
if item['section_id'] not in self.config['incl_libraries']:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if item['media_type'] == 'artist':
|
if item['media_type'] == 'artist':
|
||||||
|
@ -459,9 +452,11 @@ class RecentlyAdded(Newsletter):
|
||||||
return recently_added
|
return recently_added
|
||||||
|
|
||||||
def get_recently_added(self):
|
def get_recently_added(self):
|
||||||
self.recently_added['movie'] = self._get_recently_added('movie')
|
media_types = {s['section_type'] for s in self._get_sections()
|
||||||
self.recently_added['show'] = self._get_recently_added('show')
|
if str(s['section_id']) in self.config['incl_libraries']}
|
||||||
self.recently_added['artist'] = self._get_recently_added('artist')
|
|
||||||
|
for media_type in media_types:
|
||||||
|
self.recently_added[media_type] = self._get_recently_added(media_type)
|
||||||
|
|
||||||
return self.recently_added
|
return self.recently_added
|
||||||
|
|
||||||
|
@ -478,89 +473,19 @@ class RecentlyAdded(Newsletter):
|
||||||
)
|
)
|
||||||
|
|
||||||
def send(self, **kwargs):
|
def send(self, **kwargs):
|
||||||
if not subject or not body:
|
self.get_recently_added()
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.config['incl_subject']:
|
|
||||||
text = subject.encode('utf-8') + '\r\n' + body.encode("utf-8")
|
|
||||||
else:
|
|
||||||
text = body.encode("utf-8")
|
|
||||||
|
|
||||||
data = {'content': text}
|
|
||||||
if self.config['username']:
|
|
||||||
data['username'] = self.config['username']
|
|
||||||
if self.config['avatar_url']:
|
|
||||||
data['avatar_url'] = self.config['avatar_url']
|
|
||||||
if self.config['tts']:
|
|
||||||
data['tts'] = True
|
|
||||||
|
|
||||||
if self.config['incl_card'] and kwargs.get('parameters', {}).get('media_type'):
|
|
||||||
# Grab formatted metadata
|
|
||||||
pretty_metadata = PrettyMetadata(kwargs['parameters'])
|
|
||||||
|
|
||||||
if pretty_metadata.media_type == 'movie':
|
|
||||||
provider = self.config['movie_provider']
|
|
||||||
elif pretty_metadata.media_type in ('show', 'season', 'episode'):
|
|
||||||
provider = self.config['tv_provider']
|
|
||||||
elif pretty_metadata.media_type in ('artist', 'album', 'track'):
|
|
||||||
provider = self.config['music_provider']
|
|
||||||
else:
|
|
||||||
provider = None
|
|
||||||
|
|
||||||
poster_url = pretty_metadata.get_poster_url()
|
|
||||||
provider_name = pretty_metadata.get_provider_name(provider)
|
|
||||||
provider_link = pretty_metadata.get_provider_link(provider)
|
|
||||||
title = pretty_metadata.get_title('\xc2\xb7'.decode('utf8'))
|
|
||||||
description = pretty_metadata.get_description()
|
|
||||||
plex_url = pretty_metadata.get_plex_url()
|
|
||||||
|
|
||||||
# Build Discord post attachment
|
|
||||||
attachment = {'title': title
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.config['color']:
|
|
||||||
hex_match = re.match(r'^#([0-9a-fA-F]{3}){1,2}$', self.config['color'])
|
|
||||||
if hex_match:
|
|
||||||
hex = hex_match.group(0).lstrip('#')
|
|
||||||
hex = ''.join(h * 2 for h in hex) if len(hex) == 3 else hex
|
|
||||||
attachment['color'] = helpers.hex_to_int(hex)
|
|
||||||
|
|
||||||
if self.config['incl_thumbnail']:
|
|
||||||
attachment['thumbnail'] = {'url': poster_url}
|
|
||||||
else:
|
|
||||||
attachment['image'] = {'url': poster_url}
|
|
||||||
|
|
||||||
if self.config['incl_description'] or pretty_metadata.media_type in ('artist', 'album', 'track'):
|
|
||||||
attachment['description'] = description
|
|
||||||
|
|
||||||
fields = []
|
|
||||||
if provider_link:
|
|
||||||
attachment['url'] = provider_link
|
|
||||||
fields.append({'name': 'View Details',
|
|
||||||
'value': '[%s](%s)' % (provider_name, provider_link.encode('utf-8')),
|
|
||||||
'inline': True})
|
|
||||||
if self.config['incl_pmslink']:
|
|
||||||
fields.append({'name': 'View Details',
|
|
||||||
'value': '[Plex Web](%s)' % plex_url.encode('utf-8'),
|
|
||||||
'inline': True})
|
|
||||||
if fields:
|
|
||||||
attachment['fields'] = fields
|
|
||||||
|
|
||||||
data['embeds'] = [attachment]
|
|
||||||
|
|
||||||
headers = {'Content-type': 'application/json'}
|
|
||||||
params = {'wait': True}
|
|
||||||
|
|
||||||
return self.make_request(self.config['hook'], params=params, headers=headers, json=data)
|
|
||||||
|
|
||||||
def _get_sections(self):
|
def _get_sections(self):
|
||||||
sections_list = libraries.Libraries().get_sections()
|
return libraries.Libraries().get_sections()
|
||||||
|
|
||||||
section_options = {'': ''}
|
def _get_sections_options(self):
|
||||||
for l in sections_list:
|
sections = {'': ''}
|
||||||
section_options[l['section_id']] = l['section_name']
|
for s in self._get_sections():
|
||||||
|
if s['section_type'] != 'photo':
|
||||||
return section_options
|
sections[s['section_id']] = s['section_name']
|
||||||
|
return sections
|
||||||
|
|
||||||
def return_config_options(self):
|
def return_config_options(self):
|
||||||
config_option = [{'label': 'Number of Days',
|
config_option = [{'label': 'Number of Days',
|
||||||
|
@ -569,14 +494,12 @@ class RecentlyAdded(Newsletter):
|
||||||
'description': 'The past number of days to include in the newsletter.',
|
'description': 'The past number of days to include in the newsletter.',
|
||||||
'input_type': 'number'
|
'input_type': 'number'
|
||||||
},
|
},
|
||||||
{'label': 'Exclude Libraries',
|
{'label': 'Included Libraries',
|
||||||
'value': json.dumps(self.config['excl_libraries']),
|
'value': json.dumps(self.config['incl_libraries']),
|
||||||
'description': 'Select the libraries to exclude from the newsletter.'
|
'description': 'Select the libraries to include in the newsletter.',
|
||||||
'Leave blank to include all libraries in the newsletter.',
|
'name': 'recently_added_incl_libraries',
|
||||||
'name': 'recently_added_excl_libraries',
|
|
||||||
'input_type': 'select',
|
'input_type': 'select',
|
||||||
'select_options': self._get_sections(),
|
'select_options': self._get_sections_options()
|
||||||
'multiple': True
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -443,9 +443,9 @@ class WebInterface(object):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
json:
|
json:
|
||||||
[{"section_id": 1, "section_name": "Movies"},
|
[{"section_id": 1, "section_name": "Movies", "section_type": "movie"},
|
||||||
{"section_id": 7, "section_name": "Music"},
|
{"section_id": 7, "section_name": "Music", "section_type": "artist"},
|
||||||
{"section_id": 2, "section_name": "TV Shows"},
|
{"section_id": 2, "section_name": "TV Shows", "section_type": "show"},
|
||||||
{...}
|
{...}
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue