diff --git a/data/interfaces/default/notification_triggers_modal.html b/data/interfaces/default/notification_triggers_modal.html index bbe798fc..f6da7604 100644 --- a/data/interfaces/default/notification_triggers_modal.html +++ b/data/interfaces/default/notification_triggers_modal.html @@ -64,6 +64,13 @@ from plexpy import helpers

Trigger notification when a media item is added to the Plex Media Server.

+
+ +

Trigger notification when the Plex Media Server cannot be reached.

+
diff --git a/data/interfaces/default/settings.html b/data/interfaces/default/settings.html index 43375644..477678d7 100644 --- a/data/interfaces/default/settings.html +++ b/data/interfaces/default/settings.html @@ -658,6 +658,23 @@ available_notification_agents = sorted(notifiers.available_notification_agents() +
  • + + +
  • diff --git a/plexpy/config.py b/plexpy/config.py index 4415f2cd..00b3dac5 100644 --- a/plexpy/config.py +++ b/plexpy/config.py @@ -46,6 +46,7 @@ _CONFIG_DEFINITIONS = { 'BOXCAR_ON_BUFFER': (int, 'Boxcar', 0), 'BOXCAR_ON_WATCHED': (int, 'Boxcar', 0), 'BOXCAR_ON_CREATED': (int, 'Boxcar', 0), + 'BOXCAR_ON_DOWN': (int, 'Boxcar', 0), 'BUFFER_THRESHOLD': (int, 'Monitoring', 3), 'BUFFER_WAIT': (int, 'Monitoring', 900), 'CACHE_DIR': (str, 'General', ''), @@ -71,6 +72,7 @@ _CONFIG_DEFINITIONS = { 'EMAIL_ON_BUFFER': (int, 'Email', 0), 'EMAIL_ON_WATCHED': (int, 'Email', 0), 'EMAIL_ON_CREATED': (int, 'Email', 0), + 'EMAIL_ON_DOWN': (int, 'Email', 0), 'ENABLE_HTTPS': (int, 'General', 0), 'FIRST_RUN_COMPLETE': (int, 'General', 0), 'FREEZE_DB': (int, 'General', 0), @@ -88,6 +90,7 @@ _CONFIG_DEFINITIONS = { 'GROWL_ON_BUFFER': (int, 'Growl', 0), 'GROWL_ON_WATCHED': (int, 'Growl', 0), 'GROWL_ON_CREATED': (int, 'Growl', 0), + 'GROWL_ON_DOWN': (int, 'Growl', 0), 'HOME_LIBRARY_CARDS': (str, 'General', 'library_statistics_first'), 'HOME_STATS_LENGTH': (int, 'General', 30), 'HOME_STATS_TYPE': (int, 'General', 0), @@ -113,6 +116,7 @@ _CONFIG_DEFINITIONS = { 'IFTTT_ON_BUFFER': (int, 'IFTTT', 0), 'IFTTT_ON_WATCHED': (int, 'IFTTT', 0), 'IFTTT_ON_CREATED': (int, 'IFTTT', 0), + 'IFTTT_ON_DOWN': (int, 'IFTTT', 0), 'JOURNAL_MODE': (str, 'Advanced', 'wal'), 'LAUNCH_BROWSER': (int, 'General', 1), 'LOG_DIR': (str, 'General', ''), @@ -138,6 +142,7 @@ _CONFIG_DEFINITIONS = { 'NMA_ON_BUFFER': (int, 'NMA', 0), 'NMA_ON_WATCHED': (int, 'NMA', 0), 'NMA_ON_CREATED': (int, 'NMA', 0), + 'NMA_ON_DOWN': (int, 'NMA', 0), 'NOTIFY_CONSECUTIVE': (int, 'Monitoring', 1), 'NOTIFY_RECENTLY_ADDED_GRANDPARENT': (int, 'Monitoring', 0), 'NOTIFY_RECENTLY_ADDED_DELAY': (int, 'Monitoring', 60), @@ -156,6 +161,8 @@ _CONFIG_DEFINITIONS = { 'NOTIFY_ON_WATCHED_BODY_TEXT': (str, 'Monitoring', '{user} ({player}) has watched {title}.'), 'NOTIFY_ON_CREATED_SUBJECT_TEXT': (str, 'Monitoring', 'PlexPy ({server_name})'), 'NOTIFY_ON_CREATED_BODY_TEXT': (str, 'Monitoring', '{title} was recently added to Plex.'), + 'NOTIFY_ON_DOWN_SUBJECT_TEXT': (str, 'Monitoring', 'PlexPy ({server_name})'), + 'NOTIFY_ON_DOWN_BODY_TEXT': (str, 'Monitoring', 'The Plex server is down.'), 'OSX_NOTIFY_APP': (str, 'OSX_Notify', '/Applications/PlexPy'), 'OSX_NOTIFY_ENABLED': (int, 'OSX_Notify', 0), 'OSX_NOTIFY_ON_PLAY': (int, 'OSX_Notify', 0), @@ -165,6 +172,7 @@ _CONFIG_DEFINITIONS = { 'OSX_NOTIFY_ON_BUFFER': (int, 'OSX_Notify', 0), 'OSX_NOTIFY_ON_WATCHED': (int, 'OSX_Notify', 0), 'OSX_NOTIFY_ON_CREATED': (int, 'OSX_Notify', 0), + 'OSX_NOTIFY_ON_DOWN': (int, 'OSX_Notify', 0), 'PLEX_CLIENT_HOST': (str, 'Plex', ''), 'PLEX_ENABLED': (int, 'Plex', 0), 'PLEX_PASSWORD': (str, 'Plex', ''), @@ -176,6 +184,7 @@ _CONFIG_DEFINITIONS = { 'PLEX_ON_BUFFER': (int, 'Plex', 0), 'PLEX_ON_WATCHED': (int, 'Plex', 0), 'PLEX_ON_CREATED': (int, 'Plex', 0), + 'PLEX_ON_DOWN': (int, 'Plex', 0), 'PROWL_ENABLED': (int, 'Prowl', 0), 'PROWL_KEYS': (str, 'Prowl', ''), 'PROWL_PRIORITY': (int, 'Prowl', 0), @@ -186,6 +195,7 @@ _CONFIG_DEFINITIONS = { 'PROWL_ON_BUFFER': (int, 'Prowl', 0), 'PROWL_ON_WATCHED': (int, 'Prowl', 0), 'PROWL_ON_CREATED': (int, 'Prowl', 0), + 'PROWL_ON_DOWN': (int, 'Prowl', 0), 'PUSHALOT_APIKEY': (str, 'Pushalot', ''), 'PUSHALOT_ENABLED': (int, 'Pushalot', 0), 'PUSHALOT_ON_PLAY': (int, 'Pushalot', 0), @@ -195,6 +205,7 @@ _CONFIG_DEFINITIONS = { 'PUSHALOT_ON_BUFFER': (int, 'Pushalot', 0), 'PUSHALOT_ON_WATCHED': (int, 'Pushalot', 0), 'PUSHALOT_ON_CREATED': (int, 'Pushalot', 0), + 'PUSHALOT_ON_DOWN': (int, 'Pushalot', 0), 'PUSHBULLET_APIKEY': (str, 'PushBullet', ''), 'PUSHBULLET_DEVICEID': (str, 'PushBullet', ''), 'PUSHBULLET_CHANNEL_TAG': (str, 'PushBullet', ''), @@ -206,6 +217,7 @@ _CONFIG_DEFINITIONS = { 'PUSHBULLET_ON_BUFFER': (int, 'PushBullet', 0), 'PUSHBULLET_ON_WATCHED': (int, 'PushBullet', 0), 'PUSHBULLET_ON_CREATED': (int, 'PushBullet', 0), + 'PUSHBULLET_ON_DOWN': (int, 'PushBullet', 0), 'PUSHOVER_APITOKEN': (str, 'Pushover', ''), 'PUSHOVER_ENABLED': (int, 'Pushover', 0), 'PUSHOVER_KEYS': (str, 'Pushover', ''), @@ -218,6 +230,7 @@ _CONFIG_DEFINITIONS = { 'PUSHOVER_ON_BUFFER': (int, 'Pushover', 0), 'PUSHOVER_ON_WATCHED': (int, 'Pushover', 0), 'PUSHOVER_ON_CREATED': (int, 'Pushover', 0), + 'PUSHOVER_ON_DOWN': (int, 'Pushover', 0), 'REFRESH_USERS_INTERVAL': (int, 'Monitoring', 12), 'REFRESH_USERS_ON_STARTUP': (int, 'Monitoring', 1), 'TELEGRAM_BOT_TOKEN': (str, 'Telegram', ''), @@ -230,6 +243,7 @@ _CONFIG_DEFINITIONS = { 'TELEGRAM_ON_BUFFER': (int, 'Telegram', 0), 'TELEGRAM_ON_WATCHED': (int, 'Telegram', 0), 'TELEGRAM_ON_CREATED': (int, 'Telegram', 0), + 'TELEGRAM_ON_DOWN': (int, 'Telegram', 0), 'TV_NOTIFY_ENABLE': (int, 'Monitoring', 0), 'TV_NOTIFY_ON_START': (int, 'Monitoring', 1), 'TV_NOTIFY_ON_STOP': (int, 'Monitoring', 0), @@ -245,6 +259,7 @@ _CONFIG_DEFINITIONS = { 'TWITTER_ON_BUFFER': (int, 'Twitter', 0), 'TWITTER_ON_WATCHED': (int, 'Twitter', 0), 'TWITTER_ON_CREATED': (int, 'Twitter', 0), + 'TWITTER_ON_DOWN': (int, 'Twitter', 0), 'UPDATE_DB_INTERVAL': (int, 'General', 24), 'VERIFY_SSL_CERT': (bool_int, 'Advanced', 1), 'VIDEO_LOGGING_ENABLE': (int, 'Monitoring', 1), @@ -258,7 +273,8 @@ _CONFIG_DEFINITIONS = { 'XBMC_ON_RESUME': (int, 'XBMC', 0), 'XBMC_ON_BUFFER': (int, 'XBMC', 0), 'XBMC_ON_WATCHED': (int, 'XBMC', 0), - 'XBMC_ON_CREATED': (int, 'XBMC', 0) + 'XBMC_ON_CREATED': (int, 'XBMC', 0), + 'XBMC_ON_DOWN': (int, 'XBMC', 0) } # pylint:disable=R0902 # it might be nice to refactor for fewer instance variables diff --git a/plexpy/notification_handler.py b/plexpy/notification_handler.py index fae6db6b..1e1768c9 100644 --- a/plexpy/notification_handler.py +++ b/plexpy/notification_handler.py @@ -179,6 +179,14 @@ def notify_timeline(timeline_data=None, notify_action=None): body=notify_strings[1]) # Set the notification state in the db set_notify_state(session=timeline_data, state=notify_action, agent_info=agent) + elif notify_action == 'down': + for agent in notifiers.available_notification_agents(): + if agent['on_down'] and notify_action == 'down': + # Build and send notification + notify_strings = build_server_notify_text(state=notify_action) + notifiers.send_notification(config_id=agent['id'], + subject=notify_strings[0], + body=notify_strings[1]) else: logger.debug(u"PlexPy Notifier :: Notify timeline called but incomplete data received.") @@ -583,6 +591,42 @@ def build_notify_text(session=None, timeline=None, state=None): else: return None +def build_server_notify_text(state=None): + # Get the server name + server_name = plexpy.CONFIG.PMS_NAME + + on_down_subject = plexpy.CONFIG.NOTIFY_ON_DOWN_SUBJECT_TEXT + on_down_body = plexpy.CONFIG.NOTIFY_ON_DOWN_BODY_TEXT + + available_params = {'server_name': server_name} + + # Default text + subject_text = 'PlexPy (%s)' % server_name + + if state == 'down': + # Default body text + body_text = 'Unable to get a response from the server.' + + if on_down_subject and on_down_body: + try: + subject_text = unicode(on_down_subject).format(**available_params) + except LookupError, e: + logger.error(u"PlexPy Notifier :: Unable to parse field %s in notification subject. Using fallback." % e) + except: + logger.error(u"PlexPy Notifier :: Unable to parse custom notification subject. Using fallback.") + + try: + body_text = unicode(on_down_body).format(**available_params) + except LookupError, e: + logger.error(u"PlexPy Notifier :: Unable to parse field %s in notification body. Using fallback." % e) + except: + logger.error(u"PlexPy Notifier :: Unable to parse custom notification body. Using fallback.") + + return [subject_text, body_text] + else: + return [subject_text, body_text] + else: + return None def strip_tag(data): import re diff --git a/plexpy/notifiers.py b/plexpy/notifiers.py index 2589d388..863a597e 100644 --- a/plexpy/notifiers.py +++ b/plexpy/notifiers.py @@ -66,7 +66,8 @@ def available_notification_agents(): 'on_resume': plexpy.CONFIG.GROWL_ON_RESUME, 'on_buffer': plexpy.CONFIG.GROWL_ON_BUFFER, 'on_watched': plexpy.CONFIG.GROWL_ON_WATCHED, - 'on_created': plexpy.CONFIG.GROWL_ON_CREATED + 'on_created': plexpy.CONFIG.GROWL_ON_CREATED, + 'on_down': plexpy.CONFIG.GROWL_ON_DOWN }, {'name': 'Prowl', 'id': AGENT_IDS['Prowl'], @@ -79,7 +80,8 @@ def available_notification_agents(): 'on_resume': plexpy.CONFIG.PROWL_ON_RESUME, 'on_buffer': plexpy.CONFIG.PROWL_ON_BUFFER, 'on_watched': plexpy.CONFIG.PROWL_ON_WATCHED, - 'on_created': plexpy.CONFIG.PROWL_ON_CREATED + 'on_created': plexpy.CONFIG.PROWL_ON_CREATED, + 'on_down': plexpy.CONFIG.PROWL_ON_DOWN }, {'name': 'XBMC', 'id': AGENT_IDS['XBMC'], @@ -92,7 +94,8 @@ def available_notification_agents(): 'on_resume': plexpy.CONFIG.XBMC_ON_RESUME, 'on_buffer': plexpy.CONFIG.XBMC_ON_BUFFER, 'on_watched': plexpy.CONFIG.XBMC_ON_WATCHED, - 'on_created': plexpy.CONFIG.XBMC_ON_CREATED + 'on_created': plexpy.CONFIG.XBMC_ON_CREATED, + 'on_down': plexpy.CONFIG.XBMC_ON_DOWN }, {'name': 'Plex', 'id': AGENT_IDS['Plex'], @@ -105,7 +108,8 @@ def available_notification_agents(): 'on_resume': plexpy.CONFIG.PLEX_ON_RESUME, 'on_buffer': plexpy.CONFIG.PLEX_ON_BUFFER, 'on_watched': plexpy.CONFIG.PLEX_ON_WATCHED, - 'on_created': plexpy.CONFIG.PLEX_ON_CREATED + 'on_created': plexpy.CONFIG.PLEX_ON_CREATED, + 'on_down': plexpy.CONFIG.PLEX_ON_DOWN }, {'name': 'NotifyMyAndroid', 'id': AGENT_IDS['NMA'], @@ -118,7 +122,8 @@ def available_notification_agents(): 'on_resume': plexpy.CONFIG.NMA_ON_RESUME, 'on_buffer': plexpy.CONFIG.NMA_ON_BUFFER, 'on_watched': plexpy.CONFIG.NMA_ON_WATCHED, - 'on_created': plexpy.CONFIG.NMA_ON_CREATED + 'on_created': plexpy.CONFIG.NMA_ON_CREATED, + 'on_down': plexpy.CONFIG.NMA_ON_DOWN }, {'name': 'Pushalot', 'id': AGENT_IDS['Pushalot'], @@ -131,7 +136,8 @@ def available_notification_agents(): 'on_resume': plexpy.CONFIG.PUSHALOT_ON_RESUME, 'on_buffer': plexpy.CONFIG.PUSHALOT_ON_BUFFER, 'on_watched': plexpy.CONFIG.PUSHALOT_ON_WATCHED, - 'on_created': plexpy.CONFIG.PUSHALOT_ON_CREATED + 'on_created': plexpy.CONFIG.PUSHALOT_ON_CREATED, + 'on_down': plexpy.CONFIG.PUSHALOT_ON_DOWN }, {'name': 'Pushbullet', 'id': AGENT_IDS['Pushbullet'], @@ -144,7 +150,8 @@ def available_notification_agents(): 'on_resume': plexpy.CONFIG.PUSHBULLET_ON_RESUME, 'on_buffer': plexpy.CONFIG.PUSHBULLET_ON_BUFFER, 'on_watched': plexpy.CONFIG.PUSHBULLET_ON_WATCHED, - 'on_created': plexpy.CONFIG.PUSHBULLET_ON_CREATED + 'on_created': plexpy.CONFIG.PUSHBULLET_ON_CREATED, + 'on_down': plexpy.CONFIG.PUSHBULLET_ON_DOWN }, {'name': 'Pushover', 'id': AGENT_IDS['Pushover'], @@ -157,7 +164,8 @@ def available_notification_agents(): 'on_resume': plexpy.CONFIG.PUSHOVER_ON_RESUME, 'on_buffer': plexpy.CONFIG.PUSHOVER_ON_BUFFER, 'on_watched': plexpy.CONFIG.PUSHOVER_ON_WATCHED, - 'on_created': plexpy.CONFIG.PUSHOVER_ON_CREATED + 'on_created': plexpy.CONFIG.PUSHOVER_ON_CREATED, + 'on_down': plexpy.CONFIG.PUSHOVER_ON_DOWN }, {'name': 'Boxcar2', 'id': AGENT_IDS['Boxcar2'], @@ -170,7 +178,8 @@ def available_notification_agents(): 'on_resume': plexpy.CONFIG.BOXCAR_ON_RESUME, 'on_buffer': plexpy.CONFIG.BOXCAR_ON_BUFFER, 'on_watched': plexpy.CONFIG.BOXCAR_ON_WATCHED, - 'on_created': plexpy.CONFIG.BOXCAR_ON_CREATED + 'on_created': plexpy.CONFIG.BOXCAR_ON_CREATED, + 'on_down': plexpy.CONFIG.BOXCAR_ON_DOWN }, {'name': 'E-mail', 'id': AGENT_IDS['Email'], @@ -183,7 +192,8 @@ def available_notification_agents(): 'on_resume': plexpy.CONFIG.EMAIL_ON_RESUME, 'on_buffer': plexpy.CONFIG.EMAIL_ON_BUFFER, 'on_watched': plexpy.CONFIG.EMAIL_ON_WATCHED, - 'on_created': plexpy.CONFIG.EMAIL_ON_CREATED + 'on_created': plexpy.CONFIG.EMAIL_ON_CREATED, + 'on_down': plexpy.CONFIG.EMAIL_ON_DOWN }, {'name': 'Twitter', 'id': AGENT_IDS['Twitter'], @@ -196,7 +206,8 @@ def available_notification_agents(): 'on_resume': plexpy.CONFIG.TWITTER_ON_RESUME, 'on_buffer': plexpy.CONFIG.TWITTER_ON_BUFFER, 'on_watched': plexpy.CONFIG.TWITTER_ON_WATCHED, - 'on_created': plexpy.CONFIG.TWITTER_ON_CREATED + 'on_created': plexpy.CONFIG.TWITTER_ON_CREATED, + 'on_down': plexpy.CONFIG.TWITTER_ON_DOWN }, {'name': 'IFTTT', 'id': AGENT_IDS['IFTTT'], @@ -209,7 +220,8 @@ def available_notification_agents(): 'on_resume': plexpy.CONFIG.IFTTT_ON_RESUME, 'on_buffer': plexpy.CONFIG.IFTTT_ON_BUFFER, 'on_watched': plexpy.CONFIG.IFTTT_ON_WATCHED, - 'on_created': plexpy.CONFIG.IFTTT_ON_CREATED + 'on_created': plexpy.CONFIG.IFTTT_ON_CREATED, + 'on_down': plexpy.CONFIG.IFTTT_ON_DOWN }, {'name': 'Telegram', 'id': AGENT_IDS['Telegram'], @@ -222,7 +234,8 @@ def available_notification_agents(): 'on_resume': plexpy.CONFIG.TELEGRAM_ON_RESUME, 'on_buffer': plexpy.CONFIG.TELEGRAM_ON_BUFFER, 'on_watched': plexpy.CONFIG.TELEGRAM_ON_WATCHED, - 'on_created': plexpy.CONFIG.TELEGRAM_ON_CREATED + 'on_created': plexpy.CONFIG.TELEGRAM_ON_CREATED, + 'on_down': plexpy.CONFIG.TELEGRAM_ON_DOWN } ] @@ -240,7 +253,8 @@ def available_notification_agents(): 'on_resume': plexpy.CONFIG.OSX_NOTIFY_ON_RESUME, 'on_buffer': plexpy.CONFIG.OSX_NOTIFY_ON_BUFFER, 'on_watched': plexpy.CONFIG.OSX_NOTIFY_ON_WATCHED, - 'on_created': plexpy.CONFIG.OSX_NOTIFY_ON_CREATED + 'on_created': plexpy.CONFIG.OSX_NOTIFY_ON_CREATED, + 'on_down': plexpy.CONFIG.OSX_NOTIFY_ON_DOWN }) return agents diff --git a/plexpy/webserve.py b/plexpy/webserve.py index 249b1360..97bf78cf 100644 --- a/plexpy/webserve.py +++ b/plexpy/webserve.py @@ -462,6 +462,8 @@ class WebInterface(object): "notify_on_watched_body_text": plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT, "notify_on_created_subject_text": plexpy.CONFIG.NOTIFY_ON_CREATED_SUBJECT_TEXT, "notify_on_created_body_text": plexpy.CONFIG.NOTIFY_ON_CREATED_BODY_TEXT, + "notify_on_down_subject_text": plexpy.CONFIG.NOTIFY_ON_DOWN_SUBJECT_TEXT, + "notify_on_down_body_text": plexpy.CONFIG.NOTIFY_ON_DOWN_BODY_TEXT, "home_stats_length": plexpy.CONFIG.HOME_STATS_LENGTH, "home_stats_type": checked(plexpy.CONFIG.HOME_STATS_TYPE), "home_stats_count": plexpy.CONFIG.HOME_STATS_COUNT,