diff --git a/data/interfaces/default/css/plexwatch.css b/data/interfaces/default/css/plexwatch.css index db952922..5188978d 100644 --- a/data/interfaces/default/css/plexwatch.css +++ b/data/interfaces/default/css/plexwatch.css @@ -8399,7 +8399,7 @@ ol.test >li { background-color: #282828; width: 100%; min-width: 320px; - max-width: 768px; + max-width: 900px; } .stacked-configs > li > span { @@ -8419,12 +8419,23 @@ ol.test >li { .stacked-configs > li > span > a { float: right; color: #999; + padding-left: 10px; } .stacked-configs > li > span > a:hover { color: #eee; } +.stacked-configs > li > span > i { + cursor: pointer; + padding-right: 2px; + color: #444; +} + +.stacked-configs > li > span > i:hover { + color: #eee; +} + .stacked-configs > li > span > input[type='checkbox'] { -} \ No newline at end of file +} diff --git a/data/interfaces/default/settings.html b/data/interfaces/default/settings.html index 5b8130aa..f55b7b6d 100644 --- a/data/interfaces/default/settings.html +++ b/data/interfaces/default/settings.html @@ -275,66 +275,12 @@

Global Notifications

-
-
-
- Enable TV Notifications -
-
-
-
-
- Notify on playback start -
-
- Notify on playback stop -
-
- Notify on playback pause -
-
-
-
-
-
-
- Enable Movie Notifications -
-
-
-
-
- Notify on playback start -
-
- Notify on playback stop -
-
- Notify on playback pause -
-
-
-
-
-
-
- Enable Music Notifications -
-
-
-
-
- Notify on playback start -
-
- Notify on playback stop -
-
- Notify on playback pause -
-
-
-
+
+ Enable Movie and TV Notifications +
+
+ Enable Music Notifications +
@@ -344,23 +290,27 @@

Notification Agents

- Check the desired notification option and configure it by selecting the settings icon to the right. + Toggle the desired notification option and configure it by selecting the settings icon to the right. + Watched notifications are only applicable for video items.


- @@ -707,6 +657,47 @@ }); }); + $('.notify-toggle-icon').tooltip(); + + $('.notify-toggle-icon').each(function() { + if ($(this).data('config-value') == 1) { + $(this).css("color", "#eb8600"); + $(this).addClass("active"); + } else { + $(this).css("color", "#444"); + } + }); + + $('.notify-toggle-icon').click(function() { + var configToggle = $(this).data('id'); + var toggle = $(this); + if ($(this).hasClass("active")) { + var data = {}; + data[$(this).data('config-name')] = 0; + $.ajax({ + url: 'set_notification_config', + data: data, + async: true, + success: function(data) { + toggle.css("color", "#444"); + toggle.removeClass("active"); + } + }); + } else { + var data = {}; + data[$(this).data('config-name')] = 1; + $.ajax({ + url: 'set_notification_config', + data: data, + async: true, + success: function(data) { + toggle.css("color", "#eb8600"); + toggle.addClass("active"); + } + }); + } + }); + if ($("#tv_notify_enable").is(":checked")) { $("#tv_notify_options").show(); diff --git a/data/interfaces/default/welcome.html b/data/interfaces/default/welcome.html index b5034940..6b5dcd41 100644 --- a/data/interfaces/default/welcome.html +++ b/data/interfaces/default/welcome.html @@ -120,13 +120,10 @@ from plexpy import version

PlexPy supports a wide variety of notification options. To set up a notification agent conifgure this in Settings -> Notification Agents after you have completed this setup wizard.


- Enable notifications on Movie playback + Enable notifications on Movie and TV playback
- Enable notifications on TV playback -
-
- Enable notifications on Music playback + Enable notifications on Music playback
@@ -159,9 +156,6 @@ from plexpy import version - - - diff --git a/plexpy/config.py b/plexpy/config.py index b7f51e73..3d4d32b7 100644 --- a/plexpy/config.py +++ b/plexpy/config.py @@ -39,6 +39,9 @@ _CONFIG_DEFINITIONS = { 'API_KEY': (str, 'General', ''), 'BOXCAR_ENABLED': (int, 'Boxcar', 0), 'BOXCAR_TOKEN': (str, 'Boxcar', ''), + 'BOXCAR_ON_PLAY': (int, 'Boxcar', 0), + 'BOXCAR_ON_STOP': (int, 'Boxcar', 0), + 'BOXCAR_ON_WATCHED': (int, 'Boxcar', 0), 'CACHE_DIR': (str, 'General', ''), 'CACHE_SIZEMB': (int, 'Advanced', 32), 'CHECK_GITHUB': (int, 'General', 1), @@ -55,6 +58,9 @@ _CONFIG_DEFINITIONS = { 'EMAIL_SMTP_PASSWORD': (str, 'Email', ''), 'EMAIL_SMTP_PORT': (int, 'Email', 25), 'EMAIL_TLS': (int, 'Email', 0), + 'EMAIL_ON_PLAY': (int, 'Email', 0), + 'EMAIL_ON_STOP': (int, 'Email', 0), + 'EMAIL_ON_WATCHED': (int, 'Email', 0), 'ENABLE_HTTPS': (int, 'General', 0), 'FIRST_RUN_COMPLETE': (int, 'General', 0), 'FREEZE_DB': (int, 'General', 0), @@ -64,6 +70,9 @@ _CONFIG_DEFINITIONS = { 'GROWL_ENABLED': (int, 'Growl', 0), 'GROWL_HOST': (str, 'Growl', ''), 'GROWL_PASSWORD': (str, 'Growl', ''), + 'GROWL_ON_PLAY': (int, 'Growl', 0), + 'GROWL_ON_STOP': (int, 'Growl', 0), + 'GROWL_ON_WATCHED': (int, 'Growl', 0), 'HTTPS_CERT': (str, 'General', ''), 'HTTPS_KEY': (str, 'General', ''), 'HTTP_HOST': (str, 'General', '0.0.0.0'), @@ -91,24 +100,45 @@ _CONFIG_DEFINITIONS = { 'NMA_APIKEY': (str, 'NMA', ''), 'NMA_ENABLED': (int, 'NMA', 0), 'NMA_PRIORITY': (int, 'NMA', 0), + 'NMA_ON_PLAY': (int, 'NMA', 0), + 'NMA_ON_STOP': (int, 'NMA', 0), + 'NMA_ON_WATCHED': (int, 'NMA', 0), 'OSX_NOTIFY_APP': (str, 'OSX_Notify', '/Applications/PlexPy'), 'OSX_NOTIFY_ENABLED': (int, 'OSX_Notify', 0), + 'OSX_NOTIFY_ON_PLAY': (int, 'OSX_Notify', 0), + 'OSX_NOTIFY_ON_STOP': (int, 'OSX_Notify', 0), + 'OSX_NOTIFY_ON_WATCHED': (int, 'OSX_Notify', 0), 'PLEX_CLIENT_HOST': (str, 'Plex', ''), 'PLEX_ENABLED': (int, 'Plex', 0), 'PLEX_PASSWORD': (str, 'Plex', ''), 'PLEX_USERNAME': (str, 'Plex', ''), + 'PLEX_ON_PLAY': (int, 'Plex', 0), + 'PLEX_ON_STOP': (int, 'Plex', 0), + 'PLEX_ON_WATCHED': (int, 'Plex', 0), 'PROWL_ENABLED': (int, 'Prowl', 0), 'PROWL_KEYS': (str, 'Prowl', ''), 'PROWL_PRIORITY': (int, 'Prowl', 0), + 'PROWL_ON_PLAY': (int, 'Prowl', 0), + 'PROWL_ON_STOP': (int, 'Prowl', 0), + 'PROWL_ON_WATCHED': (int, 'Prowl', 0), 'PUSHALOT_APIKEY': (str, 'Pushalot', ''), 'PUSHALOT_ENABLED': (int, 'Pushalot', 0), + 'PUSHALOT_ON_PLAY': (int, 'Pushalot', 0), + 'PUSHALOT_ON_STOP': (int, 'Pushalot', 0), + 'PUSHALOT_ON_WATCHED': (int, 'Pushalot', 0), 'PUSHBULLET_APIKEY': (str, 'PushBullet', ''), 'PUSHBULLET_DEVICEID': (str, 'PushBullet', ''), 'PUSHBULLET_ENABLED': (int, 'PushBullet', 0), + 'PUSHBULLET_ON_PLAY': (int, 'PushBullet', 0), + 'PUSHBULLET_ON_STOP': (int, 'PushBullet', 0), + 'PUSHBULLET_ON_WATCHED': (int, 'PushBullet', 0), 'PUSHOVER_APITOKEN': (str, 'Pushover', ''), 'PUSHOVER_ENABLED': (int, 'Pushover', 0), 'PUSHOVER_KEYS': (str, 'Pushover', ''), 'PUSHOVER_PRIORITY': (int, 'Pushover', 0), + 'PUSHOVER_ON_PLAY': (int, 'Pushover', 0), + 'PUSHOVER_ON_STOP': (int, 'Pushover', 0), + 'PUSHOVER_ON_WATCHED': (int, 'Pushover', 0), 'REFRESH_USERS_INTERVAL': (int, 'Monitoring', 12), 'REFRESH_USERS_ON_STARTUP': (int, 'Monitoring', 1), 'TV_NOTIFY_ENABLE': (int, 'Monitoring', 0), @@ -125,7 +155,10 @@ _CONFIG_DEFINITIONS = { 'XBMC_ENABLED': (int, 'XBMC', 0), 'XBMC_HOST': (str, 'XBMC', ''), 'XBMC_PASSWORD': (str, 'XBMC', ''), - 'XBMC_USERNAME': (str, 'XBMC', '') + 'XBMC_USERNAME': (str, 'XBMC', ''), + 'XBMC_ON_PLAY': (int, 'XBMC', 0), + 'XBMC_ON_STOP': (int, 'XBMC', 0), + 'XBMC_ON_WATCHED': (int, 'XBMC', 0) } # pylint:disable=R0902 # it might be nice to refactor for fewer instance variables diff --git a/plexpy/monitor.py b/plexpy/monitor.py index 7830ea42..ea5fcd2c 100644 --- a/plexpy/monitor.py +++ b/plexpy/monitor.py @@ -98,7 +98,7 @@ def check_active_sessions(): if session['state'] != stream['state']: if session['state'] == 'paused': # Push any notifications - notify(stream_data=stream, notify_action='pause') + notification_handler.notify(stream_data=stream, notify_action='pause') if stream['state'] == 'paused': # The stream is still paused so we need to increment the paused_counter # Using the set config parameter as the interval, probably not the most accurate but @@ -114,7 +114,7 @@ def check_active_sessions(): monitor_db.action('DELETE FROM sessions WHERE session_key = ? AND rating_key = ?', [stream['session_key'], stream['rating_key']]) # Push any notifications - notify(stream_data=stream, notify_action='stop') + notification_handler.notify(stream_data=stream, notify_action='stop') # Write the item history on playback stop monitor_process.write_session_history(session=stream) @@ -176,7 +176,7 @@ class MonitorProcessing(object): if result == 'insert': # Push any notifications - notify(stream_data=values, notify_action='play') + notification_handler.notify(stream_data=values, notify_action='play') started = int(time.time()) # Try and grab IP address from logs @@ -360,87 +360,3 @@ class MonitorProcessing(object): logger.debug(u"PlexPy Monitor :: Unable to find IP address on fallback search. Not logging IP address.") return None - -def notify(stream_data=None, notify_action=None): - - if stream_data and notify_action: - # Get the server name - pms_connect = pmsconnect.PmsConnect() - server_name = pms_connect.get_server_pref(pref='FriendlyName') - - # Build the notification heading - notify_header = 'PlexPy (%s)' % server_name - - # Build media item title - if stream_data['media_type'] == 'episode' or stream_data['media_type'] == 'track': - item_title = '%s - %s' % (stream_data['grandparent_title'], stream_data['title']) - elif stream_data['media_type'] == 'movie': - item_title = stream_data['title'] - else: - item_title = stream_data['title'] - - if notify_action == 'play': - logger.info('PlexPy Monitor :: %s (%s) started playing %s.' % (stream_data['friendly_name'], - stream_data['player'], item_title)) - - if stream_data['media_type'] == 'movie': - if plexpy.CONFIG.MOVIE_NOTIFY_ENABLE: - - if plexpy.CONFIG.MOVIE_NOTIFY_ON_START and notify_action == 'play': - message = '%s (%s) started playing %s.' % \ - (stream_data['friendly_name'], stream_data['player'], item_title) - notification_handler.push_nofitications(message, notify_header, common.notify_strings[1]) - - elif plexpy.CONFIG.MOVIE_NOTIFY_ON_PAUSE and notify_action == 'pause': - message = '%s (%s) has paused %s.' % \ - (stream_data['friendly_name'], stream_data['player'], item_title) - notification_handler.push_nofitications(message, notify_header, common.notify_strings[1]) - - elif plexpy.CONFIG.MOVIE_NOTIFY_ON_STOP and notify_action == 'stop': - message = '%s (%s) stopped playing %s.' % \ - (stream_data['friendly_name'], stream_data['player'], item_title) - notification_handler.push_nofitications(message, notify_header, common.notify_strings[1]) - - elif stream_data['media_type'] == 'episode': - if plexpy.CONFIG.TV_NOTIFY_ENABLE: - - if plexpy.CONFIG.TV_NOTIFY_ON_START and notify_action == 'play': - message = '%s (%s) started playing %s.' % \ - (stream_data['friendly_name'], stream_data['player'], item_title) - notification_handler.push_nofitications(message, notify_header, common.notify_strings[1]) - - elif plexpy.CONFIG.TV_NOTIFY_ON_PAUSE and notify_action == 'pause': - message = '%s (%s) has paused %s.' % \ - (stream_data['friendly_name'], stream_data['player'], item_title) - notification_handler.push_nofitications(message, notify_header, common.notify_strings[1]) - - elif plexpy.CONFIG.TV_NOTIFY_ON_STOP and notify_action == 'stop': - message = '%s (%s) stopped playing %s.' % \ - (stream_data['friendly_name'], stream_data['player'], item_title) - notification_handler.push_nofitications(message, notify_header, common.notify_strings[1]) - - elif stream_data['media_type'] == 'track': - if plexpy.CONFIG.MUSIC_NOTIFY_ENABLE: - - if plexpy.CONFIG.MUSIC_NOTIFY_ON_START and notify_action == 'play': - message = '%s (%s) started playing %s.' % \ - (stream_data['friendly_name'], stream_data['player'], item_title) - notification_handler.push_nofitications(message, notify_header, common.notify_strings[1]) - - elif plexpy.CONFIG.MUSIC_NOTIFY_ON_PAUSE and notify_action == 'pause': - message = '%s (%s) has paused %s.' % \ - (stream_data['friendly_name'], stream_data['player'], item_title) - notification_handler.push_nofitications(message, notify_header, common.notify_strings[1]) - - elif plexpy.CONFIG.MUSIC_NOTIFY_ON_STOP and notify_action == 'stop': - message = '%s (%s) stopped playing %s.' % \ - (stream_data['friendly_name'], stream_data['player'], item_title) - notification_handler.push_nofitications(message, notify_header, common.notify_strings[1]) - - elif stream_data['media_type'] == 'clip': - pass - else: - logger.debug(u"PlexPy Monitor :: Notify called with unsupported media type.") - pass - else: - logger.debug(u"PlexPy Monitor :: Notify called but incomplete data received.") diff --git a/plexpy/notification_handler.py b/plexpy/notification_handler.py index f1901699..3b099789 100644 --- a/plexpy/notification_handler.py +++ b/plexpy/notification_handler.py @@ -17,74 +17,63 @@ from plexpy import logger, config, notifiers import plexpy +def notify(stream_data=None, notify_action=None): + from plexpy import pmsconnect, common + + if stream_data and notify_action: + # Get the server name + pms_connect = pmsconnect.PmsConnect() + server_name = pms_connect.get_server_pref(pref='FriendlyName') -def push_nofitications(push_message=None, subject=None, status_message=None): + # Build the notification heading + notify_header = 'PlexPy (%s)' % server_name - if push_message: - if not subject: - subject = 'PlexPy' + # Build media item title + if stream_data['media_type'] == 'episode' or stream_data['media_type'] == 'track': + item_title = '%s - %s' % (stream_data['grandparent_title'], stream_data['title']) + elif stream_data['media_type'] == 'movie': + item_title = stream_data['title'] + else: + item_title = stream_data['title'] - if plexpy.CONFIG.GROWL_ENABLED: - logger.info(u"Growl request") - growl = notifiers.GROWL() - growl.notify(push_message, status_message) + if notify_action == 'play': + logger.info('PlexPy Monitor :: %s (%s) started playing %s.' % (stream_data['friendly_name'], + stream_data['player'], item_title)) - if plexpy.CONFIG.PROWL_ENABLED: - logger.info(u"Prowl request") - prowl = notifiers.PROWL() - prowl.notify(push_message, status_message) + if stream_data['media_type'] == 'movie' or stream_data['media_type'] == 'episode': + if plexpy.CONFIG.MOVIE_NOTIFY_ENABLE or plexpy.CONFIG.TV_NOTIFY_ENABLE: - if plexpy.CONFIG.XBMC_ENABLED: - xbmc = notifiers.XBMC() - if plexpy.CONFIG.XBMC_NOTIFY: - xbmc.notify(subject, push_message) + for agent in notifiers.available_notification_agents(): + if agent['on_play'] and notify_action == 'play': + logger.debug("%s agent is configured to notify on playback start." % agent['name']) + message = '%s (%s) started playing %s.' % \ + (stream_data['friendly_name'], stream_data['player'], item_title) + notifiers.send_notification(config_id=agent['id'], subject=notify_header, body=message) + elif agent['on_stop'] and notify_action == 'stop': + logger.debug("%s agent is configured to notify on playback stop." % agent['name']) + message = '%s (%s) has stopped %s.' % \ + (stream_data['friendly_name'], stream_data['player'], item_title) + notifiers.send_notification(config_id=agent['id'], subject=notify_header, body=message) - if plexpy.CONFIG.PLEX_ENABLED: - plex = notifiers.Plex() - if plexpy.CONFIG.PLEX_NOTIFY: - plex.notify(subject, push_message) + elif stream_data['media_type'] == 'track': + if plexpy.CONFIG.MUSIC_NOTIFY_ENABLE: - if plexpy.CONFIG.NMA_ENABLED: - nma = notifiers.NMA() - nma.notify(subject, push_message) + for agent in notifiers.available_notification_agents(): + if agent['on_play'] and notify_action == 'play': + logger.debug("%s agent is configured to notify on playback start." % agent['name']) + message = '%s (%s) started playing %s.' % \ + (stream_data['friendly_name'], stream_data['player'], item_title) + notifiers.send_notification(config_id=agent['id'], subject=notify_header, body=message) + elif agent['on_stop'] and notify_action == 'stop': + logger.debug("%s agent is configured to notify on playback stop." % agent['name']) + message = '%s (%s) has stopped %s.' % \ + (stream_data['friendly_name'], stream_data['player'], item_title) + notifiers.send_notification(config_id=agent['id'], subject=notify_header, body=message) - if plexpy.CONFIG.PUSHALOT_ENABLED: - logger.info(u"Pushalot request") - pushalot = notifiers.PUSHALOT() - pushalot.notify(push_message, status_message) - - if plexpy.CONFIG.PUSHOVER_ENABLED: - logger.info(u"Pushover request") - pushover = notifiers.PUSHOVER() - pushover.notify(push_message, status_message) - - if plexpy.CONFIG.PUSHBULLET_ENABLED: - logger.info(u"PushBullet request") - pushbullet = notifiers.PUSHBULLET() - pushbullet.notify(push_message, status_message) - - if plexpy.CONFIG.TWITTER_ENABLED: - logger.info(u"Sending Twitter notification") - twitter = notifiers.TwitterNotifier() - twitter.notify_download(push_message) - - if plexpy.CONFIG.OSX_NOTIFY_ENABLED: - # TODO: Get thumb in notification - # from plexpy import cache - # c = cache.Cache() - # album_art = c.get_artwork_from_cache(None, release['AlbumID']) - logger.info(u"Sending OS X notification") - osx_notify = notifiers.OSX_NOTIFY() - osx_notify.notify(subject, push_message) - - if plexpy.CONFIG.BOXCAR_ENABLED: - logger.info(u"Sending Boxcar2 notification") - boxcar = notifiers.BOXCAR() - boxcar.notify(subject, push_message) - - if plexpy.CONFIG.EMAIL_ENABLED: - logger.info(u"Sending Email notification") - email = notifiers.Email() - email.notify(subject=subject, message=push_message) + elif stream_data['media_type'] == 'clip': + pass + else: + logger.debug(u"PlexPy Monitor :: Notify called with unsupported media type.") + pass else: - logger.warning('Notification requested but no message received.') \ No newline at end of file + logger.debug(u"PlexPy Monitor :: Notify called but incomplete data received.") diff --git a/plexpy/notifiers.py b/plexpy/notifiers.py index a5de402a..855380de 100644 --- a/plexpy/notifiers.py +++ b/plexpy/notifiers.py @@ -54,69 +54,102 @@ AGENT_IDS = {"Growl": 0, def available_notification_agents(): agents = [{'name': 'Growl', 'id': AGENT_IDS['Growl'], - 'config_name': 'growl_enabled', + 'config_prefix': 'growl', 'has_config': True, - 'state': checked(plexpy.CONFIG.GROWL_ENABLED) + 'state': checked(plexpy.CONFIG.GROWL_ENABLED), + 'on_play': plexpy.CONFIG.GROWL_ON_PLAY, + 'on_stop': plexpy.CONFIG.GROWL_ON_STOP, + 'on_watched': plexpy.CONFIG.GROWL_ON_WATCHED }, {'name': 'Prowl', 'id': AGENT_IDS['Prowl'], - 'config_name': 'prowl_enabled', + 'config_prefix': 'prowl', 'has_config': True, - 'state': checked(plexpy.CONFIG.PROWL_ENABLED) + 'state': checked(plexpy.CONFIG.PROWL_ENABLED), + 'on_play': plexpy.CONFIG.PROWL_ON_PLAY, + 'on_stop': plexpy.CONFIG.PROWL_ON_STOP, + 'on_watched': plexpy.CONFIG.PROWL_ON_WATCHED }, {'name': 'XBMC', 'id': AGENT_IDS['XBMC'], - 'config_name': 'xbmc_enabled', + 'config_prefix': 'xbmc', 'has_config': True, - 'state': checked(plexpy.CONFIG.XBMC_ENABLED) + 'state': checked(plexpy.CONFIG.XBMC_ENABLED), + 'on_play': plexpy.CONFIG.XBMC_ON_PLAY, + 'on_stop': plexpy.CONFIG.XBMC_ON_STOP, + 'on_watched': plexpy.CONFIG.XBMC_ON_WATCHED }, {'name': 'Plex', 'id': AGENT_IDS['Plex'], - 'config_name': 'plex_enabled', + 'config_prefix': 'plex', 'has_config': True, - 'state': checked(plexpy.CONFIG.PLEX_ENABLED) + 'state': checked(plexpy.CONFIG.PLEX_ENABLED), + 'on_play': plexpy.CONFIG.PLEX_ON_PLAY, + 'on_stop': plexpy.CONFIG.PLEX_ON_STOP, + 'on_watched': plexpy.CONFIG.PLEX_ON_WATCHED }, {'name': 'NotifyMyAndroid', 'id': AGENT_IDS['NMA'], - 'config_name': 'nma_enabled', + 'config_prefix': 'nma', 'has_config': True, - 'state': checked(plexpy.CONFIG.NMA_ENABLED) + 'state': checked(plexpy.CONFIG.NMA_ENABLED), + 'on_play': plexpy.CONFIG.NMA_ON_PLAY, + 'on_stop': plexpy.CONFIG.NMA_ON_STOP, + 'on_watched': plexpy.CONFIG.NMA_ON_WATCHED }, {'name': 'PushAlot', 'id': AGENT_IDS['PushAlot'], - 'config_name': 'pushalot_enabled', + 'config_prefix': 'pushalot', 'has_config': True, - 'state': checked(plexpy.CONFIG.PUSHALOT_ENABLED) + 'state': checked(plexpy.CONFIG.PUSHALOT_ENABLED), + 'on_play': plexpy.CONFIG.PUSHALOT_ON_PLAY, + 'on_stop': plexpy.CONFIG.PUSHALOT_ON_STOP, + 'on_watched': plexpy.CONFIG.PUSHALOT_ON_WATCHED }, {'name': 'PushBullet', 'id': AGENT_IDS['PushBullet'], - 'config_name': 'pushbullet_enabled', + 'config_prefix': 'pushbullet', 'has_config': True, - 'state': checked(plexpy.CONFIG.PUSHBULLET_ENABLED) + 'state': checked(plexpy.CONFIG.PUSHBULLET_ENABLED), + 'on_play': plexpy.CONFIG.PUSHBULLET_ON_PLAY, + 'on_stop': plexpy.CONFIG.PUSHBULLET_ON_STOP, + 'on_watched': plexpy.CONFIG.PUSHBULLET_ON_WATCHED }, {'name': 'PushOver', 'id': AGENT_IDS['PushOver'], - 'config_name': 'pushover_enabled', + 'config_prefix': 'pushover', 'has_config': True, - 'state': checked(plexpy.CONFIG.PUSHOVER_ENABLED) + 'state': checked(plexpy.CONFIG.PUSHOVER_ENABLED), + 'on_play': plexpy.CONFIG.PUSHOVER_ON_PLAY, + 'on_stop': plexpy.CONFIG.PUSHOVER_ON_STOP, + 'on_watched': plexpy.CONFIG.PUSHOVER_ON_WATCHED }, {'name': 'OSX Notify', 'id': AGENT_IDS['OSX Notify'], - 'config_name': 'osx_notify_enabled', + 'config_prefix': 'osx_notify', 'has_config': True, - 'state': checked(plexpy.CONFIG.OSX_NOTIFY_ENABLED) + 'state': checked(plexpy.CONFIG.OSX_NOTIFY_ENABLED), + 'on_play': plexpy.CONFIG.OSX_NOTIFY_ON_PLAY, + 'on_stop': plexpy.CONFIG.OSX_NOTIFY_ON_STOP, + 'on_watched': plexpy.CONFIG.OSX_NOTIFY_ON_WATCHED }, {'name': 'Boxcar2', 'id': AGENT_IDS['Boxcar2'], - 'config_name': 'boxcar_enabled', + 'config_prefix': 'boxcar', 'has_config': True, - 'state': checked(plexpy.CONFIG.BOXCAR_ENABLED) + 'state': checked(plexpy.CONFIG.BOXCAR_ENABLED), + 'on_play': plexpy.CONFIG.BOXCAR_ON_PLAY, + 'on_stop': plexpy.CONFIG.BOXCAR_ON_STOP, + 'on_watched': plexpy.CONFIG.BOXCAR_ON_WATCHED }, {'name': 'E-mail', 'id': AGENT_IDS['Email'], - 'config_name': 'email_enabled', + 'config_prefix': 'email', 'has_config': True, - 'state': checked(plexpy.CONFIG.EMAIL_ENABLED) + 'state': checked(plexpy.CONFIG.EMAIL_ENABLED), + 'on_play': plexpy.CONFIG.EMAIL_ON_PLAY, + 'on_stop': plexpy.CONFIG.EMAIL_ON_STOP, + 'on_watched': plexpy.CONFIG.EMAIL_ON_WATCHED } ] @@ -164,6 +197,48 @@ def get_notification_agent_config(config_id): else: return [] +def send_notification(config_id, subject, body): + if config_id: + config_id = int(config_id) + + if config_id == 0: + growl = GROWL() + growl.notify(message=body, event=subject) + elif config_id == 1: + prowl = PROWL() + prowl.notify(message=body, event=subject) + elif config_id == 2: + xbmc = XBMC() + xbmc.notify(subject=subject, message=body) + elif config_id == 3: + plex = Plex() + plex.notify(subject=subject, message=body) + elif config_id == 4: + nma = NMA() + nma.notify(subject=subject, message=body) + elif config_id == 5: + pushalot = PUSHALOT() + pushalot.notify(message=body, event=subject) + elif config_id == 6: + pushbullet = PUSHBULLET() + pushbullet.notify(message=body, subject=subject) + elif config_id == 7: + pushover = PUSHOVER() + pushover.notify(message=body, event=subject) + elif config_id == 8: + osx_notify = OSX_NOTIFY() + osx_notify.notify(title=subject, text=body) + elif config_id == 9: + boxcar = BOXCAR() + boxcar.notify(title=subject, message=body) + elif config_id == 10: + email = Email() + email.notify(subject=subject, message=body) + else: + logger.debug(u"PlexPy Notifier :: Unknown agent id received.") + else: + logger.debug(u"PlexPy Notifier :: Notification requested but no agent id received.") + class GROWL(object): """ @@ -174,6 +249,9 @@ class GROWL(object): self.enabled = plexpy.CONFIG.GROWL_ENABLED self.host = plexpy.CONFIG.GROWL_HOST self.password = plexpy.CONFIG.GROWL_PASSWORD + self.on_play = plexpy.CONFIG.GROWL_ON_PLAY + self.on_stop = plexpy.CONFIG.GROWL_ON_STOP + self.on_watched = plexpy.CONFIG.GROWL_ON_WATCHED def conf(self, options): return cherrypy.config['config'].get('Growl', options) @@ -276,6 +354,9 @@ class PROWL(object): self.enabled = plexpy.CONFIG.PROWL_ENABLED self.keys = plexpy.CONFIG.PROWL_KEYS self.priority = plexpy.CONFIG.PROWL_PRIORITY + self.on_play = plexpy.CONFIG.PROWL_ON_PLAY + self.on_stop = plexpy.CONFIG.PROWL_ON_STOP + self.on_watched = plexpy.CONFIG.PROWL_ON_WATCHED def conf(self, options): return cherrypy.config['config'].get('Prowl', options) @@ -347,6 +428,9 @@ class XBMC(object): self.hosts = plexpy.CONFIG.XBMC_HOST self.username = plexpy.CONFIG.XBMC_USERNAME self.password = plexpy.CONFIG.XBMC_PASSWORD + self.on_play = plexpy.CONFIG.XBMC_ON_PLAY + self.on_stop = plexpy.CONFIG.XBMC_ON_STOP + self.on_watched = plexpy.CONFIG.XBMC_ON_WATCHED def _sendhttp(self, host, command): url_command = urllib.urlencode(command) @@ -427,6 +511,9 @@ class Plex(object): self.client_hosts = plexpy.CONFIG.PLEX_CLIENT_HOST self.username = plexpy.CONFIG.PLEX_USERNAME self.password = plexpy.CONFIG.PLEX_PASSWORD + self.on_play = plexpy.CONFIG.PLEX_ON_PLAY + self.on_stop = plexpy.CONFIG.PLEX_ON_STOP + self.on_watched = plexpy.CONFIG.PLEX_ON_WATCHED def _sendhttp(self, host, command): @@ -500,6 +587,14 @@ class Plex(object): return config_option class NMA(object): + + def __init__(self): + self.api = plexpy.CONFIG.NMA_APIKEY + self.nma_priority = plexpy.CONFIG.NMA_PRIORITY + self.on_play = plexpy.CONFIG.NMA_ON_PLAY + self.on_stop = plexpy.CONFIG.NMA_ON_STOP + self.on_watched = plexpy.CONFIG.NMA_ON_WATCHED + def notify(self, subject=None, message=None): title = 'PlexPy' api = plexpy.CONFIG.NMA_APIKEY @@ -553,18 +648,21 @@ class PUSHBULLET(object): def __init__(self): self.apikey = plexpy.CONFIG.PUSHBULLET_APIKEY self.deviceid = plexpy.CONFIG.PUSHBULLET_DEVICEID + self.on_play = plexpy.CONFIG.PUSHBULLET_ON_PLAY + self.on_stop = plexpy.CONFIG.PUSHBULLET_ON_STOP + self.on_watched = plexpy.CONFIG.PUSHBULLET_ON_WATCHED def conf(self, options): return cherrypy.config['config'].get('PUSHBULLET', options) - def notify(self, message, event): - if not plexpy.CONFIG.PUSHBULLET_ENABLED: + def notify(self, message, subject): + if not message or not subject: return http_handler = HTTPSConnection("api.pushbullet.com") data = {'type': "note", - 'title': "PlexPy", + 'title': subject.encode("utf-8"), 'body': message.encode("utf-8")} http_handler.request("POST", @@ -574,9 +672,9 @@ class PUSHBULLET(object): body=json.dumps(data)) response = http_handler.getresponse() request_status = response.status - # logger.debug(u"PushBullet response status: %r" % request_status) - # logger.debug(u"PushBullet response headers: %r" % response.getheaders()) - # logger.debug(u"PushBullet response body: %r" % response.read()) + logger.debug(u"PushBullet response status: %r" % request_status) + logger.debug(u"PushBullet response headers: %r" % response.getheaders()) + logger.debug(u"PushBullet response body: %r" % response.read()) if request_status == 200: logger.info(u"PushBullet notifications sent.") @@ -615,6 +713,12 @@ class PUSHBULLET(object): class PUSHALOT(object): + def __init__(self): + self.api_key = plexpy.CONFIG.PUSHALOT_APIKEY + self.on_play = plexpy.CONFIG.PUSHALOT_ON_PLAY + self.on_stop = plexpy.CONFIG.PUSHALOT_ON_STOP + self.on_watched = plexpy.CONFIG.PUSHALOT_ON_WATCHED + def notify(self, message, event): if not plexpy.CONFIG.PUSHALOT_ENABLED: return @@ -669,6 +773,9 @@ class PUSHOVER(object): self.enabled = plexpy.CONFIG.PUSHOVER_ENABLED self.keys = plexpy.CONFIG.PUSHOVER_KEYS self.priority = plexpy.CONFIG.PUSHOVER_PRIORITY + self.on_play = plexpy.CONFIG.PUSHOVER_ON_PLAY + self.on_stop = plexpy.CONFIG.PUSHOVER_ON_STOP + self.on_watched = plexpy.CONFIG.PUSHOVER_ON_WATCHED if plexpy.CONFIG.PUSHOVER_APITOKEN: self.application_token = plexpy.CONFIG.PUSHOVER_APITOKEN @@ -848,6 +955,9 @@ class TwitterNotifier(object): class OSX_NOTIFY(object): def __init__(self): + self.on_play = plexpy.CONFIG.OSX_NOTIFY_ON_PLAY + self.on_stop = plexpy.CONFIG.OSX_NOTIFY_ON_STOP + self.on_watched = plexpy.CONFIG.OSX_NOTIFY_ON_WATCHED try: self.objc = __import__("objc") self.AppKit = __import__("AppKit") @@ -922,6 +1032,10 @@ class BOXCAR(object): def __init__(self): self.url = 'https://new.boxcar.io/api/notifications' + self.token = plexpy.CONFIG.BOXCAR_TOKEN + self.on_play = plexpy.CONFIG.BOXCAR_ON_PLAY + self.on_stop = plexpy.CONFIG.BOXCAR_ON_STOP + self.on_watched = plexpy.CONFIG.BOXCAR_ON_WATCHED def notify(self, title, message, rgid=None): try: @@ -957,6 +1071,11 @@ class BOXCAR(object): class Email(object): + def __init__(self): + self.on_play = plexpy.CONFIG.EMAIL_ON_PLAY + self.on_stop = plexpy.CONFIG.EMAIL_ON_STOP + self.on_watched = plexpy.CONFIG.EMAIL_ON_WATCHED + def notify(self, subject, message): message = MIMEText(message, 'plain', "utf-8") diff --git a/plexpy/webserve.py b/plexpy/webserve.py index 24e16369..d644434e 100644 --- a/plexpy/webserve.py +++ b/plexpy/webserve.py @@ -585,7 +585,7 @@ class WebInterface(object): # Write the config plexpy.CONFIG.write() - raise cherrypy.HTTPRedirect("settings") + cherrypy.response.status = 200 @cherrypy.expose def do_state_change(self, signal, title, timer):