def send_notifications(sonarr_series_id, sonarr_episode_id, message): providers = get_notifier_providers() series = get_series(sonarr_series_id) series_title = series['title'] series_year = series['year'] if series_year not in [None, '', '0']: series_year = ' ({})'.format(series_year) else: series_year = '' episode = get_episode_name(sonarr_episode_id) asset = apprise.AppriseAsset(async_mode=False) apobj = apprise.Apprise(asset=asset) for provider in providers: if provider['url'] is not None: apobj.add(provider['url']) apobj.notify( title='Bazarr notification', body="{}{} - S{:02d}E{:02d} - {} : {}".format(series_title, series_year, episode[1], episode[2], episode[0], message), )
def get_service(hass, config, discovery_info=None): """Get the Apprise notification service.""" # Create our Apprise Asset Object asset = apprise.AppriseAsset(async_mode=False) # Create our Apprise Instance (reference our asset) a_obj = apprise.Apprise(asset=asset) if config.get(CONF_FILE): # Sourced from a Configuration File a_config = apprise.AppriseConfig() if not a_config.add(config[CONF_FILE]): _LOGGER.error("Invalid Apprise config url provided") return None if not a_obj.add(a_config): _LOGGER.error("Invalid Apprise config url provided") return None if config.get(CONF_URL): # Ordered list of URLs if not a_obj.add(config[CONF_URL]): _LOGGER.error("Invalid Apprise URL(s) supplied") return None return AppriseNotificationService(a_obj)
def plugin(srv, item): """Send a message to a single Apprise plugin.""" srv.logging.debug("*** MODULE=%s: service=%s, target=%s", __file__, item.service, item.target) sender = item.config.get('sender') sender_name = item.config.get('sender_name') baseuri = item.config['baseuri'] addresses = item.addrs title = item.title body = item.message try: srv.logging.debug( "Sending notification to Apprise. target=%s, addresses=%s" % (item.target, addresses)) to = ','.join(addresses) # Create an Apprise instance. apobj = apprise.Apprise(asset=apprise.AppriseAsset(async_mode=False)) # Collect URL parameters. params = OrderedDict() if sender: params["from"] = sender if to: params["to"] = to if sender_name: params["name"] = sender_name # Add notification services by server url. uri = baseuri if params: uri += '?' + urlencode(params) apobj.add(uri) # Submit notification. outcome = apobj.notify( body=body, title=title, ) if outcome: srv.logging.info("Successfully sent message using Apprise") return True else: srv.logging.error("Sending message using Apprise failed") return False except Exception as e: srv.logging.error( "Sending message using Apprise failed. target=%s, error=%s" % (item.target, e)) return False
def test_notification(protocol, provider): provider = unquote(provider) asset = apprise.AppriseAsset(async_mode=False) apobj = apprise.Apprise(asset=asset) apobj.add(protocol + "://" + provider) apobj.notify(title='Bazarr test notification', body='Test notification') return '', 200
def plugin(srv, item): """Send a message to Apprise plugin(s).""" srv.logging.debug("*** MODULE=%s: service=%s, target=%s", __file__, item.service, item.target) addresses = item.addrs if not addresses: srv.logging.warning("Skipped sending notification to Apprise %s, " "no addresses configured" % (item.target)) return False sender = item.config.get('sender') sender_name = item.config.get('sender_name') baseuri = item.config['baseuri'] title = item.title body = item.message try: srv.logging.debug("Sending notification to Apprise %s, addresses: %s" % (item.target, addresses)) to = ','.join(addresses) # Create an Apprise instance. apobj = apprise.Apprise(asset=apprise.AppriseAsset(async_mode=False)) # Add notification services by server url. uri = '{baseuri}?from={sender}&to={to}'.format(baseuri=baseuri, sender=sender, to=to) if sender_name: uri += '&name={sender_name}'.format(sender_name=sender_name) apobj.add(uri) # Submit notification. outcome = apobj.notify( body=body, title=title, ) if outcome: srv.logging.info("Successfully sent message using Apprise") return True else: srv.logging.error("Sending message using Apprise failed") return False except Exception as e: srv.logging.error("Error sending message to %s: %s" % (item.target, e)) return False
def build_apprise(self, notifiers): asset = apprise.AppriseAsset() asset.app_id = "dockupdater" asset.app_desc = "dockupdater" asset.app_url = "https://github.com/dockupdater/dockupdater" asset.html_notify_map['info'] = '#5F87C6' apprise_obj = apprise.Apprise(asset=asset) for notifier in notifiers: if notifier: add = apprise_obj.add(notifier) if not add: self.logger.error('Could not add notifier %s', notifier) return apprise_obj
def send_notifications_movie(radarr_id, message): providers = get_notifier_providers() movie = get_movies_name(radarr_id) asset = apprise.AppriseAsset(async_mode=False) apobj = apprise.Apprise(asset=asset) for provider in providers: if provider['url'] is not None: apobj.add(provider['url']) apobj.notify( title='Bazarr notification', body="{} : {}".format(movie, message), )
def build_apprise(self): asset = apprise.AppriseAsset( image_url_mask='https://i.imgur.com/L40ksWY.png', default_extension='.png') asset.app_id = "Ouroboros" asset.app_desc = "Ouroboros" asset.app_url = "https://github.com/pyouroboros/ouroboros" asset.html_notify_map['info'] = '#5F87C6' asset.image_url_logo = 'https://bin.cajun.pro/images/ouroboros/notifications/ouroboros-logo-256x256.png' apprise_obj = apprise.Apprise(asset=asset) for notifier in self.config.notifiers: add = apprise_obj.add(notifier) if not add: self.logger.error(_('Could not add notifier %s'), notifier) return apprise_obj
def send_notifications(sonarr_series_id, sonarr_episode_id, message): providers = get_notifier_providers() series = get_series_name(sonarr_series_id) episode = get_episode_name(sonarr_episode_id) asset = apprise.AppriseAsset(async_mode=False) apobj = apprise.Apprise(asset=asset) for provider in providers: if provider['url'] is not None: apobj.add(provider['url']) apobj.notify( title='Bazarr notification', body="{} - S{:02d}E{:02d} - {} : {}".format(series, episode[1], episode[2], episode[0], message), )
def __init__(self): self._logger = logging.getLogger() try: with open("./config.json") as w: self._logger.debug( "Loading Notification Data from config.json") cfg = json.load(w) self._logger.debug("Notification Data loaded successfully" + str(cfg)) self._notifier = apprise.Apprise(asset=apprise.AppriseAsset( image_url_mask= "https://avatars3.githubusercontent.com/u/3368377?s=200&v=4", default_extension=".jpeg")) for k, v in cfg['notifications'].items(): if (v['enabled'] == True): self._notifier.add(v['url']) except Exception as e: self._logger.exception( "Problem encountered when creating Notification object") sys.exit(1)
def post_notifications(event: Event, notification_urls=list[str], hard_fail=False, attachment=None): asset = apprise.AppriseAsset(async_mode=False) apobj = apprise.Apprise(asset=asset) for dest in notification_urls: status = apobj.add(dest) if not status and hard_fail: raise Exception("Apprise URL Add Failed") print(attachment) apobj.notify( body=event.text, title=event.title, attach=str(attachment), )
def send_notifications_movie(radarr_id, message): providers = get_notifier_providers() movie = get_movie(radarr_id) movie_title = movie['title'] movie_year = movie['year'] if movie_year not in [None, '', '0']: movie_year = ' ({})'.format(movie_year) else: movie_year = '' asset = apprise.AppriseAsset(async_mode=False) apobj = apprise.Apprise(asset=asset) for provider in providers: if provider['url'] is not None: apobj.add(provider['url']) apobj.notify( title='Bazarr notification', body="{}{} : {}".format(movie_title, movie_year, message), )
def test_apprise_interpret_escapes(mock_post): """ API: Apprise() interpret-escapse tests """ # Prepare Mock mock_post.return_value = requests.Request() mock_post.return_value.status_code = requests.codes.ok # Default Escapes interpretation Mode is set to disable asset = apprise.AppriseAsset() assert asset.interpret_escapes is False # Load our asset a = apprise.Apprise(asset=asset) # add a test server assert a.add("json://localhost") is True # Our servers should carry this flag a[0].asset.interpret_escapes is False # Send notification assert a.notify("ab\\ncd") is True # Test our call count assert mock_post.call_count == 1 # content is not escaped loads(mock_post.call_args_list[0][1]['data'])\ .get('message', '') == 'ab\\ncd' # Reset mock_post.reset_mock() # Send notification and provide override: assert a.notify("ab\\ncd", interpret_escapes=True) is True # Test our call count assert mock_post.call_count == 1 # content IS escaped loads(mock_post.call_args_list[0][1]['data'])\ .get('message', '') == 'ab\ncd' # Reset mock_post.reset_mock() # # Now we test the reverse setup where we set the AppriseAsset # object to True but force it off through the notify() calls # # Default Escapes interpretation Mode is set to disable asset = apprise.AppriseAsset(interpret_escapes=True) assert asset.interpret_escapes is True # Load our asset a = apprise.Apprise(asset=asset) # add a test server assert a.add("json://localhost") is True # Our servers should carry this flag a[0].asset.interpret_escapes is True # Send notification assert a.notify("ab\\ncd") is True # Test our call count assert mock_post.call_count == 1 # content IS escaped loads(mock_post.call_args_list[0][1]['data'])\ .get('message', '') == 'ab\ncd' # Reset mock_post.reset_mock() # Send notification and provide override: assert a.notify("ab\\ncd", interpret_escapes=False) is True # Test our call count assert mock_post.call_count == 1 # content is NOT escaped loads(mock_post.call_args_list[0][1]['data'])\ .get('message', '') == 'ab\\ncd'
def test_apprise_escaping_py3(mock_post): """ API: Apprise() Python v3.x escaping """ a = apprise.Apprise() response = mock.Mock() response.content = '' response.status_code = requests.codes.ok mock_post.return_value = response # Create ourselves a test object to work with a.add('json://localhost') # Escape our content assert a.notify( title="\\r\\ntitle\\r\\n", body="\\r\\nbody\\r\\n", interpret_escapes=True) # Verify our content was escaped correctly assert mock_post.call_count == 1 result = loads(mock_post.call_args_list[0][1]['data']) assert result['title'] == 'title' assert result['message'] == '\r\nbody' # Reset our mock object mock_post.reset_mock() # # Support Specially encoded content: # # Escape our content assert a.notify( # Google Translated to Arabic: "Let's make the world a better place." title='دعونا نجعل العالم مكانا أفضل.\\r\\t\\t\\n\\r\\n', # Google Translated to Hungarian: "One line of code at a time.' body='Egy sor kódot egyszerre.\\r\\n\\r\\r\\n', # Our Escape Flag interpret_escapes=True) # Verify our content was escaped correctly assert mock_post.call_count == 1 result = loads(mock_post.call_args_list[0][1]['data']) assert result['title'] == 'دعونا نجعل العالم مكانا أفضل.' assert result['message'] == 'Egy sor kódot egyszerre.' # Error handling # # We can't escape the content below assert a.notify( title=None, body=4, interpret_escapes=True) is False assert a.notify( title=4, body=None, interpret_escapes=True) is False assert a.notify( title=object(), body=False, interpret_escapes=True) is False assert a.notify( title=False, body=object(), interpret_escapes=True) is False # We support bytes assert a.notify( title=b'byte title', body=b'byte body', interpret_escapes=True) is True # However they're escaped as 'utf-8' by default unless we tell Apprise # otherwise # Now test hebrew types (outside of default utf-8) # כותרת נפלאה translates to 'A wonderful title' # זו הודעה translates to 'This is a notification' title = 'כותרת נפלאה'.encode('ISO-8859-8') body = '[_[זו הודעה](http://localhost)_'.encode('ISO-8859-8') assert a.notify( title=title, body=body, interpret_escapes=True) is False # However if we let Apprise know in advance the encoding, it will handle # it for us asset = apprise.AppriseAsset(encoding='ISO-8859-8') a = apprise.Apprise(asset=asset) # Create ourselves a test object to work with a.add('json://localhost') assert a.notify( title=title, body=body, interpret_escapes=True) is True # We'll restore our configuration back to how it was now a = apprise.Apprise() a.add('json://localhost') # The body is proessed first, so the errors thrown above get tested on # the body only. Now we run similar tests but only make the title # bad and always mark the body good assert a.notify( title=None, body="valid", interpret_escapes=True) is True assert a.notify( title=4, body="valid", interpret_escapes=True) is False assert a.notify( title=object(), body="valid", interpret_escapes=True) is False assert a.notify( title=False, body="valid", interpret_escapes=True) is True # Bytes are supported assert a.notify( title=b'byte title', body="valid", interpret_escapes=True) is True