def test_bad_token(self): p = get_notifier('telegram') data = {'token': 'foo', 'chat_id': 1, 'message': 'foo'} with pytest.raises(NotificationError) as e: rsp = p.notify(**data) rsp.raise_on_errors() assert 'Not Found' in e.value.message
def test_missing_chat_id(self): p = get_notifier('telegram') data = {'chat_id': 1, 'message': 'foo'} with pytest.raises(NotificationError) as e: rsp = p.notify(**data) rsp.raise_on_errors() assert 'chat not found' in e.value.message
def test_slack_metadata(self): p = get_notifier('slack') assert p.metadata == { 'base_url': 'https://hooks.slack.com/services/', 'provider_name': 'slack', 'site_url': 'https://api.slack.com/incoming-webhooks' }
def __init__(self, config_path: str = '~/.dotfiles/.notifers.yaml'): """__init__. Parameters ---------- config_path : str The path to config file with yaml type. The config will be used buy [notifiers](https://github.com/liiight/notifiers) For example ```yaml provider: telegram kwargs: chat_id: <Your Chat ID> token: <Your token> ``` """ # TODO: DEBUG mode path = Path(config_path).expanduser() if not path.exists(): msg = f'Can\'t find the config file for notifiers: {path}' logger.warning(msg) raise FileExistsError(msg) else: with path.open() as f: self.config = yaml.load(f, Loader=yaml.FullLoader) self._provider = get_notifier(self.config['provider']) kwargs = self.config['kwargs'] self._ntf = partial(self._provider.notify, **kwargs)
def test_get_notifier(self, mock_provider): """Test ``get_notifier()`` helper function""" from notifiers import get_notifier p = get_notifier("mock_provider") assert p assert isinstance(p, Provider)
def test_gmail_metadata(self): p = get_notifier('gmail') assert p.metadata == { 'base_url': 'smtp.gmail.com', 'provider_name': 'gmail', 'site_url': 'https://www.google.com/gmail/about/' }
def test_metadata(self): t = get_notifier('telegram') assert t.metadata == { 'base_url': 'https://api.telegram.org/bot{token}/{method}', 'provider_name': 'telegram', 'site_url': 'https://core.telegram.org/' }
def test_pushover_metadata(self): p = get_notifier('pushover') assert {'base_url': 'https://api.pushover.net/1/messages.json', 'site_url': 'https://pushover.net/', 'provider_name': 'pushover', 'sounds': ['pushover', 'bike', 'bugle', 'cashregister', 'classical', 'cosmic', 'falling', 'gamelan', 'incoming', 'intermission', 'magic', 'mechanical', 'pianobar', 'siren', 'spacealarm', 'tugboat', 'alien', 'climb', 'persistent', 'echo', 'updown', 'none'] } == p.metadata
async def send_notifier(message: AlarmMessage): provider = get_notifier(settings.NOTIFIER_PROVIDER) if settings.EMAILS_ENABLED: # provider.defaults["from"]="*****@*****.**" provider.notify(to=settings.EMAILS_TO, subject="this is alarm mail from watchmen data platform", message="[" + message.severity + "] :" + message.message, from_=settings.EMAILS_FROM_EMAIL, username=settings.SMTP_USER, password=settings.SMTP_PASSWORD, host=settings.SMTP_HOST, port=settings.SMTP_PORT, tls=settings.SMTP_TLS)
def test_metadata(self): p = get_notifier('gitter') assert p.metadata == { 'base_url': 'https://api.gitter.im/v1/rooms', 'message_url': 'https://api.gitter.im/v1/rooms/{room_id}/chatMessages', 'provider_name': 'gitter', 'site_url': 'https://gitter.im' }
def notify_via_notifiers(msg): params = {} paramlist = os.environ["DEB_CHECKER_NOTIFIERS"].split(",") for param in paramlist[1:]: key, val = param.split("=") params[key] = val # send it telegram = get_notifier(paramlist[0]) telegram.notify(message=msg, **params)
def test_metadata(self): p = get_notifier(self.notifier_name) assert p.metadata == { 'base_url': 'https://{group}.hipchat.com', 'provider_name': 'hipchat', 'room_url': '/v2/room/{room}/notification', 'site_url': 'https://www.hipchat.com/docs/apiv2', 'user_url': '/v2/user/{user}/message' }
def test_all_options(self): p = get_notifier('telegram') data = { 'parse_mode': 'markdown', 'disable_web_page_preview': True, 'disable_notification': True, 'message': '_foo_' } rsp = p.notify(**data) rsp.raise_on_errors()
def test_pushover_priority_2_restrictions(self, data, message): """Pushover specific API restrictions when using priority 2""" p = get_notifier('pushover') base_data = {'message': 'foo', 'priority': 2} final_data = {**base_data, **data} rsp = p.notify(**final_data) with pytest.raises(NotificationError) as e: rsp.raise_on_errors() print(e.value.message) assert message in e.value.message
def test_smtp_no_host(self): p = get_notifier('email') data = {'to': 'foo', 'message': 'bar'} with pytest.raises(NotificationError) as e: rsp = p.notify(**data) rsp.raise_on_errors() assert any(error in e.value.message for error in ['Errno 111', 'Errno 61']) assert any(error in rsp_error for rsp_error in rsp.errors for error in ['Errno 111', 'Errno 61'])
def test_smtp_no_host(self): p = get_notifier('email') data = {'to': 'foo', 'message': 'bar', 'host': 'http://nohost'} with pytest.raises(NotificationError) as e: rsp = p.notify(**data) rsp.raise_on_errors() possible_errors = ['Errno 111', 'Errno 61', 'Errno 8', 'Errno -2'] assert any(error in e.value.message for error in possible_errors), \ f'Error not in expected errors; {e.value.message}' assert any(error in rsp_error for rsp_error in rsp.errors for error in possible_errors), \ f'Error not in expected errors; {rsp.errors}'
def inform_telegram(offers, url, timestamp_started): #print(f'Telegram msg-sent placeholder: {offers} offers found on {url}') #return None #try: # create message message = f'--- {offers} Offers ---\nURL: {url}\nStarted: {timestamp_started}' #send message telegram = get_notifier('telegram') telegram_status = telegram.notify(message=message, token=credentials.bot_token, chat_id=credentials.chat_id) print(f'Successfully informed Telegram channel: {telegram_status}')
def test_all_options(self): p = get_notifier('pushbullet') data = { 'message': 'foo', 'type': 'link', 'url': 'https://google.com', 'title': '❤', # todo add the rest } rsp = p.notify(**data) rsp.raise_on_errors()
def __init__(self, name: str, **kwargs: typing.Any): """ Initialize method for the generic notifier :param name: The name of this notifier, is used to instantiate the underlying provider :param kwargs: Any additional arguments to be passed to the provider at construction """ from .logger import logger self.logger = logger self.name = name self._notifier = notifiers.get_notifier(self.name) self._kwargs = kwargs
def test_smtp_sanity(self): """using Gmail SMTP""" data = { 'message': '<b>foo</b>', 'host': 'smtp.gmail.com', 'port': 587, 'tls': True, 'html': True } p = get_notifier('email') rsp = p.notify(**data) rsp.raise_on_errors()
def __init__( self, level: int = 5, service: str = None, formatter: str = None, service_kwargs: dict = None, ): if level > 5: level = 5 self.level = level self.service = notifiers.get_notifier(service) self.formatter = formatter self.service_kwargs = service_kwargs
def test_bad_request(self): p = get_notifier(self.notifier_name) data = { 'token': 'foo', 'room': 'baz', 'message': 'bar', 'id': 'bla', 'group': 'nada' } with pytest.raises(NotificationError) as e: rsp = p.notify(**data) rsp.raise_on_errors() assert 'Invalid OAuth session' in e.value.message
def provider_group_factory(): """Dynamically generate provider groups for all providers, and add all basic command to it""" for provider in all_providers(): p = get_notifier(provider) provider_name = p.name help = f"Options for '{provider_name}'" group = click.Group(name=provider_name, help=help) # Notify command notify = partial(_notify, p=p) group.add_command( schema_to_command(p, "notify", notify, add_message=True)) # Resources command resources_callback = partial(_resources, p=p) resources_cmd = click.Command( "resources", callback=resources_callback, help="Show provider resources list", ) group.add_command(resources_cmd) pretty_opt = click.Option(["--pretty/--not-pretty"], help="Output a pretty version of the JSON") # Add any provider resources for resource in p.resources: rsc = getattr(p, resource) rsrc_callback = partial(_resource, rsc) rsrc_command = schema_to_command(rsc, resource, rsrc_callback, add_message=False) rsrc_command.params.append(pretty_opt) group.add_command(rsrc_command) for name, description in CORE_COMMANDS.items(): callback = func_factory(p, name) params = [pretty_opt] command = click.Command( name, callback=callback, help=description.format(provider_name), params=params, ) group.add_command(command) notifiers_cli.add_command(group)
def get_services_list(): services = {} services_names = [] for service in AbstractService.__subclasses__(): if service != NotifierService: srv = service() services[srv.get_type()] = srv services_names.append(srv.get_type()) for notifier_service in notifiers.core.all_providers(): if notifier_service not in CONFIG_NOTIFIER_IGNORE: NotifierService.NOTIFIER_PROVIDER_TYPE = notifiers.get_notifier( notifier_service) srv = NotifierService() services[srv.get_provider_name()] = srv services_names.append(srv.get_provider_name()) return services, services_names
def test_all_options(self): """Use all available pushover options""" p = get_notifier('pushover') data = {'message': 'foo', 'title': 'title', 'priority': 2, 'url': 'http://foo.com', 'url_title': 'url title', 'sound': 'bike', 'timestamp': 0, 'retry': 30, 'expire': 30, 'callback': 'http://callback.com', 'html': 1} rsp = p.notify(**data) rsp.raise_on_errors()
def send_notification(message, providerName, providerData): '''Sends a notification to the user''' # Log call logging.info('Preparing to send notification to user using provider "%s"', providerName) # Send notification to user provider = notifiers.get_notifier(providerName) result = provider.notify(message=message, **providerData) # Log result if result.status == notifiers.SUCCESS_STATUS: logging.info("Notification successfully sent") else: logging.error("Notifying user failed with error(s): %s", repr(result.errors))
def enablePushover(self, userkey, APIkey): self.pushover = namedtuple('Pushover', 'notifier APIkey userkey')( get_notifier('pushover'), APIkey, userkey, ) defaults = { 'user': userkey, 'token': APIkey, } handler = NotificationHandler('pushover', defaults=defaults) handler.setLevel(logging.ERROR) handler.setFormatter(logging.Formatter('%(asctime)s - %(message)s')) log = logging.getLogger() log.addHandler(handler) self.notify('Pushover enabled for logging')
def enableTelegram(self, chatID, token): self.telegram = namedtuple('Telegram', 'notifier chatID token')( get_notifier('telegram'), chatID, token, ) defaults = { 'chat_id': chatID, 'token': token, } handler = NotificationHandler('telegram', defaults=defaults) handler.setLevel(logging.ERROR) handler.setFormatter(logging.Formatter('%(asctime)s - %(message)s')) log = logging.getLogger() log.addHandler(handler) self.notify('Telegram enabled for logging')
def __init__(self, config_path: str = "~/.dotfiles/.notifiers.yaml", idle=False): """__init__. Parameters ---------- config_path : str The path to config file with yaml type. The config will be used buy [notifiers](https://github.com/liiight/notifiers) For example ```yaml provider: telegram kwargs: chat_id: <Your Chat ID> token: <Your token> ``` If you need proxy for your provider, please use the config below. The env will be updated when running `ntf` method [This solution](https://github.com/liiight/notifiers/issues/236) is proposed by notifiers ``` env: HTTP_PROXY: 'http://IP:PORT' HTTPS_PROXY: 'http://IP:PORT' ``` """ # TODO: DEBUG mode path = Path(config_path).expanduser() if not path.exists(): msg = f"Can't find the config file for notifiers: {path}" logger.warning(msg) raise FileExistsError(msg) else: with path.open() as f: self.config = yaml.load(f, Loader=yaml.FullLoader) logger.remove() log_level = self.config.get("log_level", "INFO") logger.add(sys.stderr, level=log_level) logger.debug(f"log level: {log_level}") self._provider = get_notifier(self.config["provider"]) kwargs = self.config["kwargs"] self._ntf = partial(self._provider.notify, **kwargs) self.env = self.config.get("env", {}) self._idle = idle
def _send_push_notifications( title, subtitle, message, provider_config_factory: Optional[Callable[[str, str, str], dict]] = None, ): """Send push notifications.""" try: import notifiers except (ImportError, ModuleNotFoundError): raise KlaxonExit( os.linesep.join( [ "notifiers enabled but not installed", "$ pip(x) install klaxon[notifiers]", ] ) ) if "notifiers" not in config: raise KlaxonExit("notifiers key not found in configuration") message = message.strip('"').strip("'") provider_config = ( get_notifiers_provider_config(message, subtitle, title) if provider_config_factory is None else provider_config_factory(message, subtitle, title) ) for provider in config["notifiers"]: name = provider["name"] kwargs = { **provider_config.get(name, {}), **{k: v for k, v in provider.items() if k != "name"}, } if ( "message" in notifiers.get_notifier(name).required["required"] and "message" not in kwargs ): kwargs["message"] = message notifiers.notify(name, **kwargs)