async def webhook(self, request): json_data = await request.json() try: repo_name = json_data['repository']['repo_name'] owner = json_data['repository']['owner'] except KeyError: logger.info('Could not parse webhook data %s.', json_data) return aiohttp.web.Response(status=406, text='unparseable webhook') uuid = DockerhubDal.read_by_repository(repo_name) if uuid: channel = users.UsersDal.read(uuid[0])[6] ch = helper.get_channel_or_fail(logger, self.slack, channel) self.send_now(ch, IMAGE_PUSHED(repo_name)) return aiohttp.web.Response(text='ok') uuid = DockerhubDal.read_by_username(owner) if uuid: channel = users.UsersDal.read(uuid[0])[6] ch = helper.get_channel_or_fail(logger, self.slack, channel) self.send_now(ch, IMAGE_PUSHED(repo_name)) return aiohttp.web.Response(text='ok') logger.debug('Received valid but unsupported webhook for %s.', repo_name) return aiohttp.web.Response(status=406, text='unsupported repository')
def respond(self, ch, user, msg): for fn in self.response_fns: groups = self.check_words(fn, msg) or self.check_regex(fn, msg) if not groups: continue if hasattr(fn, 'auth') and not users.UsersDal.is_admin(user): self.send(ch, messages.NO_AUTHORIZATION) for channel in channels.ChannelsDal.read(admin_only=True): c = helper.get_channel_or_fail(logger, self.slack, channel) self.send(c, messages.UNAUTHORIZED_USAGE(user, msg)) continue if inspect.iscoroutinefunction(fn): asyncio.ensure_future(fn(self, ch, user, groups)) else: fn(self, ch, user, groups) for channel, msgs in self.buffer.items(): self.send_now(channel, '\n'.join(msgs)) self.reset_buffer() return True
def init(self): logger.debug('Initializing database...') schema.initialize() logger.debug('Initializing plugins...') for name in sorted(os.listdir('/plugins')): plugin = importlib.machinery.SourceFileLoader( name, '/plugins/{}/__init__.py'.format(name)).load_module() plugin = getattr(plugin, plugin.__all__[0])(self.slack) plugin.initialize() logger.debug('Initializing users...') user_list = self.slack.api_call('users.list') for user in user_list['members']: if user['deleted']: continue if user['is_bot'] or user['id'] == 'USLACKBOT': continue user = helper.get_user_fields(self.slack, user) users.UsersDal.create(*user) c = helper.get_channel_or_fail(logger, self.slack, user[-1]) c.send_message(messages.GREET_USER(user))
def run(self): logger.debug('Configuring event loop...') loop = asyncio.get_event_loop() loop.set_exception_handler(async.looping_exception_handler) asyncio.ensure_future(self.slack.keepalive()) asyncio.ensure_future(self.rtm_respond()) app = aiohttp.web.Application() logger.debug('Initializing plugins...') for name in sorted(os.listdir('/plugins')): plugin = importlib.machinery.SourceFileLoader( name, '/plugins/{}/__init__.py'.format(name)).load_module() plugin = getattr(plugin, plugin.__all__[0])(self.slack) self.plugins.append(plugin) for function in plugin.loop_fns: asyncio.ensure_future(function(plugin)) for function in plugin.api_fns: app.router.add_route(function.method, function.route, functools.partial(function, plugin)) logger.debug('Building web server...') handler = app.make_handler(access_log=None) f = loop.create_server(handler, '0.0.0.0', 8080) srv = loop.run_until_complete(f) try: logger.debug('Running') loop.run_forever() except KeyboardInterrupt: pass finally: srv.close() loop.run_until_complete(srv.wait_closed()) loop.run_until_complete(app.shutdown()) loop.run_until_complete(handler.finish_connections(60.0)) loop.run_until_complete(app.cleanup()) loop.close() if not loop.exception: return for channel in channels.ChannelsDal.read(admin_only=True): c = helper.get_channel_or_fail(logger, self.slack, channel) c.send_message(messages.DEATH(loop.exception)) sys.exit(1)
def handle_message(self, channel, text, user): ch = helper.get_channel_or_fail(logger, self.slack, channel) if 'help' in text: message = [messages.DESCRIBE(__version__)] for plugin in self.plugins: message.append('- {}'.format(plugin.name)) if plugin.name in text: plugin.help(ch=ch) break else: ch.send_message('\n'.join(message)) return for plugin in self.plugins: plugin.respond(ch=ch, user=user, msg=text)
def respond(self, ch, user, msg): for fn in self.response_fns: groups = self.check_words(fn, msg) or self.check_regex(fn, msg) if not groups: continue if hasattr(fn, 'auth') and not users.UsersDal.is_admin(user): self.send(ch, messages.NO_AUTHORIZATION()) for channel in channels.ChannelsDal.read(admin_only=True): c = helper.get_channel_or_fail(logger, self.slack, channel) self.send(c, messages.UNAUTHORIZED_USAGE(user, msg)) continue fn(self, ch, user, groups) for channel, msgs in self.buffer.items(): self.send_now(channel, '\n'.join(msgs)) self.reset_buffer() return True
def respond(self, ch, user, msg): for fn in self.response_fns: regex_match = fn.regex.match(msg) if not regex_match: continue if hasattr(fn, 'auth') and not users.UsersDal.is_admin(user): self.send(ch, messages.NO_AUTHORIZATION()) for channel in channels.ChannelsDal.read(admin_only=True): c = helper.get_channel_or_fail(logger, self.slack, channel) self.send(c, messages.UNAUTHORIZED_USAGE(user, msg)) continue fn(self, ch, user, regex_match.groups()) for channel, msgs in self.buffer.iteritems(): self.send_now(channel, '\n'.join(msgs)) self.reset_buffer() return
def handle_message(self, channel, text, user): ch = helper.get_channel_or_fail(logger, self.slack, channel) if 'help' in text: message = [messages.DESCRIBE(__version__)] for plugin in self.plugins: message.append('- {}'.format(plugin.name)) if plugin.name in text: plugin.help(ch=ch) break else: ch.send_message('\n'.join(message)) return responded = False for plugin in self.plugins: responded ^= bool(plugin.respond(ch=ch, user=user, msg=text)) if not responded: logger.warning('Could not understand message "%s".', text) sentry.captureMessage('Could not understand message', extra={'msg': text}) ch.send_message(messages.CONFUSED)
def update(self): ch = helper.get_channel_or_fail(logger, self.slack, 'general') ch.send_message(messages.UPDATED(__version__))
def __init__(self, slack): super(Status, self).__init__(slack, 'status') for channel in channels.ChannelsDal.read(admin_only=True): ch = helper.get_channel_or_fail(logger, self.slack, channel) self.send_now(ch, messages.ONLINE())
def __init__(self, slack): super().__init__(slack) for channel in channels.ChannelsDal.read(admin_only=True): ch = helper.get_channel_or_fail(logger, self.slack, channel) self.send_now(ch, ONLINE)