More rename, more -python2
This commit is contained in:
@@ -15,60 +15,40 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
from __future__ import division
|
||||
from __future__ import unicode_literals
|
||||
from future.builtins import next
|
||||
from future.builtins import map
|
||||
from future.builtins import str
|
||||
from future.builtins import range
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import threading
|
||||
import time
|
||||
from collections import Counter, defaultdict
|
||||
from functools import partial
|
||||
from itertools import groupby
|
||||
from operator import itemgetter
|
||||
from string import Formatter
|
||||
|
||||
import arrow
|
||||
import bleach
|
||||
from collections import Counter, defaultdict
|
||||
from functools import partial
|
||||
import hashlib
|
||||
from itertools import groupby
|
||||
import json
|
||||
from operator import itemgetter
|
||||
import os
|
||||
import re
|
||||
from string import Formatter
|
||||
import threading
|
||||
import time
|
||||
|
||||
import musicbrainzngs
|
||||
|
||||
import jellypy
|
||||
if jellypy.PYTHON2:
|
||||
import activity_processor
|
||||
import common
|
||||
import database
|
||||
import datafactory
|
||||
import logger
|
||||
import helpers
|
||||
import notifiers
|
||||
import pmsconnect
|
||||
import request
|
||||
from newsletter_handler import notify as notify_newsletter
|
||||
else:
|
||||
from jellypy import activity_processor
|
||||
from jellypy import common
|
||||
from jellypy import database
|
||||
from jellypy import datafactory
|
||||
from jellypy import logger
|
||||
from jellypy import helpers
|
||||
from jellypy import notifiers
|
||||
from jellypy import pmsconnect
|
||||
from jellypy import request
|
||||
from jellypy.newsletter_handler import notify as notify_newsletter
|
||||
from jellypy import activity_processor
|
||||
from jellypy import common
|
||||
from jellypy import database
|
||||
from jellypy import datafactory
|
||||
from jellypy import logger
|
||||
from jellypy import helpers
|
||||
from jellypy import notifiers
|
||||
from jellypy import pmsconnect
|
||||
from jellypy import request
|
||||
from jellypy.newsletter_handler import notify as notify_newsletter
|
||||
|
||||
|
||||
def process_queue():
|
||||
queue = jellypy.NOTIFY_QUEUE
|
||||
while True:
|
||||
params = queue.get()
|
||||
|
||||
|
||||
if params is None:
|
||||
break
|
||||
elif params:
|
||||
@@ -88,14 +68,16 @@ def process_queue():
|
||||
|
||||
|
||||
def start_threads(num_threads=1):
|
||||
logger.info("Tautulli NotificationHandler :: Starting background notification handler ({} threads).".format(num_threads))
|
||||
logger.info(
|
||||
"Tautulli NotificationHandler :: Starting background notification handler ({} threads).".format(num_threads))
|
||||
for x in range(num_threads):
|
||||
thread = threading.Thread(target=process_queue)
|
||||
thread.daemon = True
|
||||
thread.start()
|
||||
|
||||
|
||||
def add_notifier_each(notifier_id=None, notify_action=None, stream_data=None, timeline_data=None, manual_trigger=False, **kwargs):
|
||||
def add_notifier_each(notifier_id=None, notify_action=None, stream_data=None, timeline_data=None, manual_trigger=False,
|
||||
**kwargs):
|
||||
if not notify_action:
|
||||
logger.debug("Tautulli NotificationHandler :: Notify called but no action received.")
|
||||
return
|
||||
@@ -119,7 +101,8 @@ def add_notifier_each(notifier_id=None, notify_action=None, stream_data=None, ti
|
||||
|
||||
if notifiers_enabled and (manual_trigger or conditions):
|
||||
if manual_trigger:
|
||||
logger.debug("Tautulli NotificationHandler :: Notifiers enabled for notify_action '%s' (manual trigger)." % notify_action)
|
||||
logger.debug(
|
||||
"Tautulli NotificationHandler :: Notifiers enabled for notify_action '%s' (manual trigger)." % notify_action)
|
||||
|
||||
if stream_data or timeline_data:
|
||||
# Build the notification parameters
|
||||
@@ -150,7 +133,9 @@ def add_notifier_each(notifier_id=None, notify_action=None, stream_data=None, ti
|
||||
data.update(kwargs)
|
||||
jellypy.NOTIFY_QUEUE.put(data)
|
||||
else:
|
||||
logger.debug("Tautulli NotificationHandler :: Custom notification conditions not satisfied, skipping notifier_id %s." % notifier['id'])
|
||||
logger.debug(
|
||||
"Tautulli NotificationHandler :: Custom notification conditions not satisfied, skipping notifier_id %s." %
|
||||
notifier['id'])
|
||||
|
||||
# Add on_concurrent and on_newdevice to queue if action is on_play
|
||||
if notify_action == 'on_play':
|
||||
@@ -187,7 +172,8 @@ def notify_conditions(notify_action=None, stream_data=None, timeline_data=None):
|
||||
user_sessions = [s for s in result['sessions'] if s['user_id'] == stream_data['user_id']]
|
||||
|
||||
if jellypy.CONFIG.NOTIFY_CONCURRENT_BY_IP:
|
||||
evaluated = len(Counter(s['ip_address'] for s in user_sessions)) >= jellypy.CONFIG.NOTIFY_CONCURRENT_THRESHOLD
|
||||
evaluated = len(
|
||||
Counter(s['ip_address'] for s in user_sessions)) >= jellypy.CONFIG.NOTIFY_CONCURRENT_THRESHOLD
|
||||
else:
|
||||
evaluated = len(user_sessions) >= jellypy.CONFIG.NOTIFY_CONCURRENT_THRESHOLD
|
||||
|
||||
@@ -202,8 +188,10 @@ def notify_conditions(notify_action=None, stream_data=None, timeline_data=None):
|
||||
|
||||
if notify_action == 'on_stop':
|
||||
evaluated = (jellypy.CONFIG.NOTIFY_CONSECUTIVE or
|
||||
(stream_data['media_type'] == 'movie' and progress_percent < jellypy.CONFIG.MOVIE_WATCHED_PERCENT) or
|
||||
(stream_data['media_type'] == 'episode' and progress_percent < jellypy.CONFIG.TV_WATCHED_PERCENT))
|
||||
(stream_data[
|
||||
'media_type'] == 'movie' and progress_percent < jellypy.CONFIG.MOVIE_WATCHED_PERCENT) or
|
||||
(stream_data[
|
||||
'media_type'] == 'episode' and progress_percent < jellypy.CONFIG.TV_WATCHED_PERCENT))
|
||||
|
||||
elif notify_action == 'on_resume':
|
||||
evaluated = jellypy.CONFIG.NOTIFY_CONSECUTIVE or progress_percent < 99
|
||||
@@ -218,7 +206,8 @@ def notify_conditions(notify_action=None, stream_data=None, timeline_data=None):
|
||||
else:
|
||||
evaluated = False
|
||||
|
||||
logger.debug("Tautulli NotificationHandler :: Global notification conditions evaluated to '{}'.".format(evaluated))
|
||||
logger.debug(
|
||||
"Tautulli NotificationHandler :: Global notification conditions evaluated to '{}'.".format(evaluated))
|
||||
# Recently Added notifications
|
||||
elif timeline_data:
|
||||
|
||||
@@ -272,7 +261,7 @@ def notify_custom_conditions(notifier_id=None, parameters=None):
|
||||
if not parameter or not operator or not values:
|
||||
evaluated = True
|
||||
evaluated_conditions.append(evaluated)
|
||||
logger.debug("Tautulli NotificationHandler :: {%s} Blank condition > %s" % (i+1, evaluated))
|
||||
logger.debug("Tautulli NotificationHandler :: {%s} Blank condition > %s" % (i + 1, evaluated))
|
||||
continue
|
||||
|
||||
# Make sure the condition values is in a list
|
||||
@@ -291,8 +280,9 @@ def notify_custom_conditions(notifier_id=None, parameters=None):
|
||||
values = [helpers.cast_to_float(v) for v in values]
|
||||
|
||||
except ValueError as e:
|
||||
logger.error("Tautulli NotificationHandler :: {%s} Unable to cast condition '%s', values '%s', to type '%s'."
|
||||
% (i+1, parameter, values, parameter_type))
|
||||
logger.error(
|
||||
"Tautulli NotificationHandler :: {%s} Unable to cast condition '%s', values '%s', to type '%s'."
|
||||
% (i + 1, parameter, values, parameter_type))
|
||||
return False
|
||||
|
||||
# Cast the parameter value to the correct type
|
||||
@@ -307,8 +297,9 @@ def notify_custom_conditions(notifier_id=None, parameters=None):
|
||||
parameter_value = helpers.cast_to_float(parameter_value)
|
||||
|
||||
except ValueError as e:
|
||||
logger.error("Tautulli NotificationHandler :: {%s} Unable to cast parameter '%s', value '%s', to type '%s'."
|
||||
% (i+1, parameter, parameter_value, parameter_type))
|
||||
logger.error(
|
||||
"Tautulli NotificationHandler :: {%s} Unable to cast parameter '%s', value '%s', to type '%s'."
|
||||
% (i + 1, parameter, parameter_value, parameter_type))
|
||||
return False
|
||||
|
||||
# Check each condition
|
||||
@@ -339,11 +330,12 @@ def notify_custom_conditions(notifier_id=None, parameters=None):
|
||||
else:
|
||||
evaluated = None
|
||||
logger.warn("Tautulli NotificationHandler :: {%s} Invalid condition operator '%s' > %s."
|
||||
% (i+1, operator, evaluated))
|
||||
% (i + 1, operator, evaluated))
|
||||
|
||||
evaluated_conditions.append(evaluated)
|
||||
logger.debug("Tautulli NotificationHandler :: {%s} %s | %s | %s > '%s' > %s"
|
||||
% (i+1, parameter, operator, ' or '.join(["'%s'" % v for v in values]), parameter_value, evaluated))
|
||||
% (i + 1, parameter, operator, ' or '.join(["'%s'" % v for v in values]), parameter_value,
|
||||
evaluated))
|
||||
|
||||
if logic_groups:
|
||||
# Format and evaluate the logic string
|
||||
@@ -357,7 +349,7 @@ def notify_custom_conditions(notifier_id=None, parameters=None):
|
||||
else:
|
||||
evaluated_logic = all(evaluated_conditions[1:])
|
||||
logger.debug("Tautulli NotificationHandler :: Condition logic [blank]: %s > %s"
|
||||
% (' and '.join(['{%s}' % (i+1) for i in range(len(custom_conditions))]), evaluated_logic))
|
||||
% (' and '.join(['{%s}' % (i + 1) for i in range(len(custom_conditions))]), evaluated_logic))
|
||||
|
||||
logger.debug("Tautulli NotificationHandler :: Custom conditions evaluated to '{}'. Conditions: {}.".format(
|
||||
evaluated_logic, evaluated_conditions[1:]))
|
||||
@@ -457,7 +449,6 @@ def get_notify_state_enabled(session, notify_action, notified=True):
|
||||
|
||||
|
||||
def set_notify_state(notifier, notify_action, subject='', body='', script_args='', session=None):
|
||||
|
||||
if notifier and notify_action:
|
||||
monitor_db = database.MonitorDatabase()
|
||||
|
||||
@@ -571,7 +562,8 @@ def build_media_notify_params(notify_action=None, session=None, timeline=None, m
|
||||
total_bandwidth = lan_bandwidth + wan_bandwidth
|
||||
|
||||
# Generate a combined transcode decision value
|
||||
if session.get('stream_video_decision', '') == 'transcode' or session.get('stream_audio_decision', '') == 'transcode':
|
||||
if session.get('stream_video_decision', '') == 'transcode' or session.get('stream_audio_decision',
|
||||
'') == 'transcode':
|
||||
transcode_decision = 'Transcode'
|
||||
elif session.get('stream_video_decision', '') == 'copy' or session.get('stream_audio_decision', '') == 'copy':
|
||||
transcode_decision = 'Direct Stream'
|
||||
@@ -597,7 +589,8 @@ def build_media_notify_params(notify_action=None, session=None, timeline=None, m
|
||||
else:
|
||||
plex_web_rating_key = notify_params['rating_key']
|
||||
|
||||
notify_params['plex_url'] = '{web_url}#!/server/{pms_identifier}/details?key=%2Flibrary%2Fmetadata%2F{rating_key}'.format(
|
||||
notify_params[
|
||||
'plex_url'] = '{web_url}#!/server/{pms_identifier}/details?key=%2Flibrary%2Fmetadata%2F{rating_key}'.format(
|
||||
web_url=jellypy.CONFIG.PMS_WEB_URL,
|
||||
pms_identifier=jellypy.CONFIG.PMS_IDENTIFIER,
|
||||
rating_key=plex_web_rating_key)
|
||||
@@ -621,7 +614,8 @@ def build_media_notify_params(notify_action=None, session=None, timeline=None, m
|
||||
notify_params['trakt_url'] = 'https://trakt.tv/search/imdb/' + notify_params['imdb_id']
|
||||
|
||||
if 'thetvdb://' in notify_params['guid'] or notify_params['thetvdb_id']:
|
||||
notify_params['thetvdb_id'] = notify_params['thetvdb_id'] or notify_params['guid'].split('thetvdb://')[1].split('/')[0].split('?')[0]
|
||||
notify_params['thetvdb_id'] = notify_params['thetvdb_id'] or \
|
||||
notify_params['guid'].split('thetvdb://')[1].split('/')[0].split('?')[0]
|
||||
notify_params['thetvdb_url'] = 'https://thetvdb.com/?tab=series&id=' + notify_params['thetvdb_id']
|
||||
notify_params['trakt_url'] = 'https://trakt.tv/search/tvdb/' + notify_params['thetvdb_id'] + '?type=show'
|
||||
|
||||
@@ -632,12 +626,15 @@ def build_media_notify_params(notify_action=None, session=None, timeline=None, m
|
||||
|
||||
if 'themoviedb://' in notify_params['guid'] or notify_params['themoviedb_id']:
|
||||
if notify_params['media_type'] == 'movie':
|
||||
notify_params['themoviedb_id'] = notify_params['themoviedb_id'] or notify_params['guid'].split('themoviedb://')[1].split('?')[0]
|
||||
notify_params['themoviedb_id'] = notify_params['themoviedb_id'] or \
|
||||
notify_params['guid'].split('themoviedb://')[1].split('?')[0]
|
||||
notify_params['themoviedb_url'] = 'https://www.themoviedb.org/movie/' + notify_params['themoviedb_id']
|
||||
notify_params['trakt_url'] = 'https://trakt.tv/search/tmdb/' + notify_params['themoviedb_id'] + '?type=movie'
|
||||
notify_params['trakt_url'] = 'https://trakt.tv/search/tmdb/' + notify_params[
|
||||
'themoviedb_id'] + '?type=movie'
|
||||
|
||||
elif notify_params['media_type'] in ('show', 'season', 'episode'):
|
||||
notify_params['themoviedb_id'] = notify_params['themoviedb_id'] or notify_params['guid'].split('themoviedb://')[1].split('/')[0].split('?')[0]
|
||||
notify_params['themoviedb_id'] = notify_params['themoviedb_id'] or \
|
||||
notify_params['guid'].split('themoviedb://')[1].split('/')[0].split('?')[0]
|
||||
notify_params['themoviedb_url'] = 'https://www.themoviedb.org/tv/' + notify_params['themoviedb_id']
|
||||
notify_params['trakt_url'] = 'https://trakt.tv/search/tmdb/' + notify_params['themoviedb_id'] + '?type=show'
|
||||
|
||||
@@ -710,7 +707,8 @@ def build_media_notify_params(notify_action=None, session=None, timeline=None, m
|
||||
|
||||
if tvmaze_info.get('thetvdb_id'):
|
||||
notify_params['thetvdb_url'] = 'https://thetvdb.com/?tab=series&id=' + str(tvmaze_info['thetvdb_id'])
|
||||
notify_params['trakt_url'] = 'https://trakt.tv/search/tvdb/{}' + str(notify_params['thetvdb_id']) + '?type=show'
|
||||
notify_params['trakt_url'] = 'https://trakt.tv/search/tvdb/{}' + str(
|
||||
notify_params['thetvdb_id']) + '?type=show'
|
||||
if tvmaze_info.get('imdb_id'):
|
||||
notify_params['imdb_url'] = 'https://www.imdb.com/title/' + tvmaze_info['imdb_id']
|
||||
notify_params['trakt_url'] = 'https://trakt.tv/search/imdb/' + notify_params['imdb_id']
|
||||
@@ -779,7 +777,7 @@ def build_media_notify_params(notify_action=None, session=None, timeline=None, m
|
||||
notify_params.update(poster_info)
|
||||
|
||||
if ((manual_trigger or jellypy.CONFIG.NOTIFY_GROUP_RECENTLY_ADDED_GRANDPARENT)
|
||||
and notify_params['media_type'] in ('show', 'artist')):
|
||||
and notify_params['media_type'] in ('show', 'artist')):
|
||||
show_name = notify_params['title']
|
||||
episode_name = ''
|
||||
artist_name = notify_params['title']
|
||||
@@ -999,15 +997,15 @@ def build_media_notify_params(notify_action=None, session=None, timeline=None, m
|
||||
'track_count': grandchild_count,
|
||||
'year': notify_params['year'],
|
||||
'release_date': arrow.get(notify_params['originally_available_at']).format(date_format)
|
||||
if notify_params['originally_available_at'] else '',
|
||||
if notify_params['originally_available_at'] else '',
|
||||
'air_date': arrow.get(notify_params['originally_available_at']).format(date_format)
|
||||
if notify_params['originally_available_at'] else '',
|
||||
if notify_params['originally_available_at'] else '',
|
||||
'added_date': arrow.get(notify_params['added_at']).format(date_format)
|
||||
if notify_params['added_at'] else '',
|
||||
if notify_params['added_at'] else '',
|
||||
'updated_date': arrow.get(notify_params['updated_at']).format(date_format)
|
||||
if notify_params['updated_at'] else '',
|
||||
if notify_params['updated_at'] else '',
|
||||
'last_viewed_date': arrow.get(notify_params['last_viewed_at']).format(date_format)
|
||||
if notify_params['last_viewed_at'] else '',
|
||||
if notify_params['last_viewed_at'] else '',
|
||||
'studio': notify_params['studio'],
|
||||
'content_rating': notify_params['content_rating'],
|
||||
'directors': ', '.join(notify_params['directors']),
|
||||
@@ -1019,7 +1017,7 @@ def build_media_notify_params(notify_action=None, session=None, timeline=None, m
|
||||
'summary': notify_params['summary'],
|
||||
'tagline': notify_params['tagline'],
|
||||
'rating': rating,
|
||||
'critic_rating': critic_rating,
|
||||
'critic_rating': critic_rating,
|
||||
'audience_rating': audience_rating,
|
||||
'user_rating': notify_params['user_rating'],
|
||||
'duration': duration,
|
||||
@@ -1089,7 +1087,7 @@ def build_media_notify_params(notify_action=None, session=None, timeline=None, m
|
||||
'parent_thumb': notify_params['parent_thumb'],
|
||||
'grandparent_thumb': notify_params['grandparent_thumb'],
|
||||
'poster_thumb': poster_thumb
|
||||
}
|
||||
}
|
||||
|
||||
return available_params
|
||||
|
||||
@@ -1147,7 +1145,7 @@ def build_server_notify_params(notify_action=None, **kwargs):
|
||||
'update_version': pms_download_info['version'],
|
||||
'update_url': pms_download_info['download_url'],
|
||||
'update_release_date': arrow.get(pms_download_info['release_date']).format(date_format)
|
||||
if pms_download_info['release_date'] else '',
|
||||
if pms_download_info['release_date'] else '',
|
||||
'update_channel': 'Beta' if update_channel == 'beta' else 'Public',
|
||||
'update_platform': pms_download_info['platform'],
|
||||
'update_distro': pms_download_info['distro'],
|
||||
@@ -1164,7 +1162,7 @@ def build_server_notify_params(notify_action=None, **kwargs):
|
||||
'tautulli_update_commit': kwargs.pop('plexpy_update_commit', ''),
|
||||
'tautulli_update_behind': kwargs.pop('plexpy_update_behind', ''),
|
||||
'tautulli_update_changelog': plexpy_download_info['body']
|
||||
}
|
||||
}
|
||||
|
||||
return available_params
|
||||
|
||||
@@ -1189,8 +1187,8 @@ def build_notify_text(subject='', body='', notify_action=None, parameters=None,
|
||||
media_type = parameters.get('media_type')
|
||||
|
||||
all_tags = r'<movie>.*?</movie>|' \
|
||||
'<show>.*?</show>|<season>.*?</season>|<episode>.*?</episode>|' \
|
||||
'<artist>.*?</artist>|<album>.*?</album>|<track>.*?</track>'
|
||||
'<show>.*?</show>|<season>.*?</season>|<episode>.*?</episode>|' \
|
||||
'<artist>.*?</artist>|<album>.*?</album>|<track>.*?</track>'
|
||||
|
||||
# Check for exclusion tags
|
||||
if media_type == 'movie':
|
||||
@@ -1200,7 +1198,8 @@ def build_notify_text(subject='', body='', notify_action=None, parameters=None,
|
||||
elif media_type == 'season':
|
||||
pattern = re.compile(all_tags.replace('<season>.*?</season>', '<season>|</season>'), re.IGNORECASE | re.DOTALL)
|
||||
elif media_type == 'episode':
|
||||
pattern = re.compile(all_tags.replace('<episode>.*?</episode>', '<episode>|</episode>'), re.IGNORECASE | re.DOTALL)
|
||||
pattern = re.compile(all_tags.replace('<episode>.*?</episode>', '<episode>|</episode>'),
|
||||
re.IGNORECASE | re.DOTALL)
|
||||
elif media_type == 'artist':
|
||||
pattern = re.compile(all_tags.replace('<artist>.*?</artist>', '<artist>|</artist>'), re.IGNORECASE | re.DOTALL)
|
||||
elif media_type == 'album':
|
||||
@@ -1224,10 +1223,12 @@ def build_notify_text(subject='', body='', notify_action=None, parameters=None,
|
||||
try:
|
||||
script_args = [str_formatter(arg) for arg in helpers.split_args(subject)]
|
||||
except LookupError as e:
|
||||
logger.error("Tautulli NotificationHandler :: Unable to parse parameter %s in script argument. Using fallback." % e)
|
||||
logger.error(
|
||||
"Tautulli NotificationHandler :: Unable to parse parameter %s in script argument. Using fallback." % e)
|
||||
script_args = []
|
||||
except Exception as e:
|
||||
logger.exception("Tautulli NotificationHandler :: Unable to parse custom script arguments: %s. Using fallback." % e)
|
||||
logger.exception(
|
||||
"Tautulli NotificationHandler :: Unable to parse custom script arguments: %s. Using fallback." % e)
|
||||
script_args = []
|
||||
|
||||
elif agent_id == 25:
|
||||
@@ -1235,51 +1236,61 @@ def build_notify_text(subject='', body='', notify_action=None, parameters=None,
|
||||
try:
|
||||
subject = json.loads(subject)
|
||||
except ValueError as e:
|
||||
logger.error("Tautulli NotificationHandler :: Unable to parse custom webhook json header data: %s. Using fallback." % e)
|
||||
logger.error(
|
||||
"Tautulli NotificationHandler :: Unable to parse custom webhook json header data: %s. Using fallback." % e)
|
||||
subject = ''
|
||||
if subject:
|
||||
try:
|
||||
subject = json.dumps(helpers.traverse_map(subject, str_formatter))
|
||||
except LookupError as e:
|
||||
logger.error("Tautulli NotificationHandler :: Unable to parse parameter %s in webhook header data. Using fallback." % e)
|
||||
logger.error(
|
||||
"Tautulli NotificationHandler :: Unable to parse parameter %s in webhook header data. Using fallback." % e)
|
||||
subject = ''
|
||||
except Exception as e:
|
||||
logger.exception("Tautulli NotificationHandler :: Unable to parse custom webhook header data: %s. Using fallback." % e)
|
||||
logger.exception(
|
||||
"Tautulli NotificationHandler :: Unable to parse custom webhook header data: %s. Using fallback." % e)
|
||||
subject = ''
|
||||
|
||||
if body:
|
||||
try:
|
||||
body = json.loads(body)
|
||||
except ValueError as e:
|
||||
logger.error("Tautulli NotificationHandler :: Unable to parse custom webhook json body data: %s. Using fallback." % e)
|
||||
logger.error(
|
||||
"Tautulli NotificationHandler :: Unable to parse custom webhook json body data: %s. Using fallback." % e)
|
||||
body = ''
|
||||
if body:
|
||||
try:
|
||||
body = json.dumps(helpers.traverse_map(body, str_formatter))
|
||||
except LookupError as e:
|
||||
logger.error("Tautulli NotificationHandler :: Unable to parse parameter %s in webhook body data. Using fallback." % e)
|
||||
logger.error(
|
||||
"Tautulli NotificationHandler :: Unable to parse parameter %s in webhook body data. Using fallback." % e)
|
||||
body = ''
|
||||
except Exception as e:
|
||||
logger.exception("Tautulli NotificationHandler :: Unable to parse custom webhook body data: %s. Using fallback." % e)
|
||||
logger.exception(
|
||||
"Tautulli NotificationHandler :: Unable to parse custom webhook body data: %s. Using fallback." % e)
|
||||
body = ''
|
||||
|
||||
else:
|
||||
try:
|
||||
subject = str_formatter(subject)
|
||||
except LookupError as e:
|
||||
logger.error("Tautulli NotificationHandler :: Unable to parse parameter %s in notification subject. Using fallback." % e)
|
||||
logger.error(
|
||||
"Tautulli NotificationHandler :: Unable to parse parameter %s in notification subject. Using fallback." % e)
|
||||
subject = str(default_subject).format(**parameters)
|
||||
except Exception as e:
|
||||
logger.exception("Tautulli NotificationHandler :: Unable to parse custom notification subject: %s. Using fallback." % e)
|
||||
logger.exception(
|
||||
"Tautulli NotificationHandler :: Unable to parse custom notification subject: %s. Using fallback." % e)
|
||||
subject = str(default_subject).format(**parameters)
|
||||
|
||||
try:
|
||||
body = str_formatter(body)
|
||||
except LookupError as e:
|
||||
logger.error("Tautulli NotificationHandler :: Unable to parse parameter %s in notification body. Using fallback." % e)
|
||||
logger.error(
|
||||
"Tautulli NotificationHandler :: Unable to parse parameter %s in notification body. Using fallback." % e)
|
||||
body = str(default_body).format(**parameters)
|
||||
except Exception as e:
|
||||
logger.exception("Tautulli NotificationHandler :: Unable to parse custom notification body: %s. Using fallback." % e)
|
||||
logger.exception(
|
||||
"Tautulli NotificationHandler :: Unable to parse custom notification body: %s. Using fallback." % e)
|
||||
body = str(default_body).format(**parameters)
|
||||
|
||||
return subject, body, script_args
|
||||
@@ -1325,7 +1336,7 @@ def format_group_index(group_keys):
|
||||
num = []
|
||||
num00 = []
|
||||
|
||||
for k, g in groupby(enumerate(group_keys), lambda i_x: i_x[0]-i_x[1]):
|
||||
for k, g in groupby(enumerate(group_keys), lambda i_x: i_x[0] - i_x[1]):
|
||||
group = list(map(itemgetter(1), g))
|
||||
g_min, g_max = min(group), max(group)
|
||||
|
||||
@@ -1499,14 +1510,16 @@ def lookup_tvmaze_by_id(rating_key=None, thetvdb_id=None, imdb_id=None, title=No
|
||||
'WHERE rating_key = ?'
|
||||
tvmaze_info = db.select_single(query, args=[rating_key])
|
||||
except Exception as e:
|
||||
logger.warn("Tautulli NotificationHandler :: Unable to execute database query for lookup_tvmaze_by_tvdb_id: %s." % e)
|
||||
logger.warn(
|
||||
"Tautulli NotificationHandler :: Unable to execute database query for lookup_tvmaze_by_tvdb_id: %s." % e)
|
||||
return {}
|
||||
|
||||
if not tvmaze_info:
|
||||
tvmaze_info = {}
|
||||
|
||||
if thetvdb_id:
|
||||
logger.debug("Tautulli NotificationHandler :: Looking up TVmaze info for thetvdb_id '{}'.".format(thetvdb_id))
|
||||
logger.debug(
|
||||
"Tautulli NotificationHandler :: Looking up TVmaze info for thetvdb_id '{}'.".format(thetvdb_id))
|
||||
elif imdb_id:
|
||||
logger.debug("Tautulli NotificationHandler :: Looking up TVmaze info for imdb_id '{}'.".format(imdb_id))
|
||||
else:
|
||||
@@ -1559,18 +1572,23 @@ def lookup_themoviedb_by_id(rating_key=None, thetvdb_id=None, imdb_id=None, titl
|
||||
'WHERE rating_key = ?'
|
||||
themoviedb_info = db.select_single(query, args=[rating_key])
|
||||
except Exception as e:
|
||||
logger.warn("Tautulli NotificationHandler :: Unable to execute database query for lookup_themoviedb_by_imdb_id: %s." % e)
|
||||
logger.warn(
|
||||
"Tautulli NotificationHandler :: Unable to execute database query for lookup_themoviedb_by_imdb_id: %s." % e)
|
||||
return {}
|
||||
|
||||
if not themoviedb_info:
|
||||
themoviedb_info = {}
|
||||
|
||||
if thetvdb_id:
|
||||
logger.debug("Tautulli NotificationHandler :: Looking up The Movie Database info for thetvdb_id '{}'.".format(thetvdb_id))
|
||||
logger.debug(
|
||||
"Tautulli NotificationHandler :: Looking up The Movie Database info for thetvdb_id '{}'.".format(
|
||||
thetvdb_id))
|
||||
elif imdb_id:
|
||||
logger.debug("Tautulli NotificationHandler :: Looking up The Movie Database info for imdb_id '{}'.".format(imdb_id))
|
||||
logger.debug(
|
||||
"Tautulli NotificationHandler :: Looking up The Movie Database info for imdb_id '{}'.".format(imdb_id))
|
||||
else:
|
||||
logger.debug("Tautulli NotificationHandler :: Looking up The Movie Database info for '{} ({})'.".format(title, year))
|
||||
logger.debug(
|
||||
"Tautulli NotificationHandler :: Looking up The Movie Database info for '{} ({})'.".format(title, year))
|
||||
|
||||
params = {'api_key': jellypy.CONFIG.THEMOVIEDB_APIKEY}
|
||||
|
||||
@@ -1648,10 +1666,12 @@ def get_themoviedb_info(rating_key=None, media_type=None, themoviedb_id=None):
|
||||
|
||||
themoviedb_json = {}
|
||||
|
||||
logger.debug("Tautulli NotificationHandler :: Looking up The Movie Database info for themoviedb_id '{}'.".format(themoviedb_id))
|
||||
logger.debug("Tautulli NotificationHandler :: Looking up The Movie Database info for themoviedb_id '{}'.".format(
|
||||
themoviedb_id))
|
||||
|
||||
params = {'api_key': jellypy.CONFIG.THEMOVIEDB_APIKEY}
|
||||
response, err_msg, req_msg = request.request_response2('https://api.themoviedb.org/3/{}/{}'.format(media_type, themoviedb_id), params=params)
|
||||
response, err_msg, req_msg = request.request_response2(
|
||||
'https://api.themoviedb.org/3/{}/{}'.format(media_type, themoviedb_id), params=params)
|
||||
|
||||
if response and not err_msg:
|
||||
themoviedb_json = response.json()
|
||||
@@ -1876,7 +1896,7 @@ class CustomFormatter(Formatter):
|
||||
else:
|
||||
format_spec, auto_arg_index = self._vformat(
|
||||
format_spec, args, kwargs,
|
||||
used_args, recursion_depth-1,
|
||||
used_args, recursion_depth - 1,
|
||||
auto_arg_index=auto_arg_index)
|
||||
|
||||
# format the object and append to the result
|
||||
|
||||
Reference in New Issue
Block a user