150:498f984cd1ef
Anton Shestakov <av6@dwimlabs.net>, Sun, 17 Jul 2016 22:38:03 +0800
queue: add hook handler (only for bitbucket at the moment)

next change 151:640c160d89a2

hooks-queue.py

Permissions: -rwxr-xr-x

Other formats: Feeds:
#!/usr/bin/env python
import json
import logging
from argparse import ArgumentParser, FileType, SUPPRESS
import redis
import yaml
from tornado.ioloop import IOLoop
from tornado.options import define, options
from tornado.web import Application, RequestHandler, URLSpec
from candolint.utils import lookup_option, timestamp
define('listen', metavar='IP', default='127.0.0.1')
define('port', metavar='PORT', default=8034, type=int)
define('xheaders', metavar='True|False', default=False, type=bool)
options.logging = None
class BitbucketHookHandler(RequestHandler):
def post(self):
payload = json.loads(self.request.body)
base = {
'url': payload['repository']['links']['html']['href'],
'scm': payload['repository']['scm'],
'repo': payload['repository']['name'],
'timestamp': timestamp(),
'source': 'bitbucket.org'
}
items = []
for change in payload['push']['changes']:
for head in change['new']['heads']:
item = base.copy()
item.update(change=head['hash'])
items.append(item)
for item in items:
data = json.dumps(item)
logging.debug('Pushing %s', data)
self.rconn.rpush('candolint:queue:changes', data)
logging.info('Pushed a change for %s', data['repo'])
self.finish({'message': 'OK, added {}'.format(len(items))})
@property
def rconn(self):
return self.application.rconn
class CandolintHooks(Application):
def __init__(self, rconn, debug):
handlers = [
URLSpec(r'/bb', BitbucketHookHandler),
]
super(CandolintHooks, self).__init__(handlers, debug=debug)
self.rconn = rconn
def listen(self, port, address='', **kwargs):
name = self.__class__.__name__
logging.info('%s is serving on %s:%d', name, address, port)
super(CandolintHooks, self).listen(port, address, **kwargs)
def main():
parser = ArgumentParser(argument_default=SUPPRESS)
parser.add_argument(
'-c', '--config', type=FileType('r'),
help='configuration file (YAML)')
parser.add_argument(
'-d', '--debug', action='store_true', default=False,
help='enable debugging output')
group = parser.add_argument_group(
'queue configuration',
'these options that can also be specified in the configuration file')
group.add_argument('--redis-host', help='(default: 127.0.0.1)')
group.add_argument('--redis-port', type=int, help='(default: 6379)')
group.add_argument('--redis-password')
args, extra = parser.parse_known_args()
options.parse_command_line(extra)
config = yaml.safe_load(args.config) if hasattr(args, 'config') else {}
rhost = lookup_option('redis-host', args, config, default='127.0.0.1')
rport = lookup_option('redis-port', args, config, default=6379)
rpass = lookup_option('redis-password', args, config)
logging.basicConfig(
level=logging.DEBUG if args.debug else logging.INFO,
format='%(asctime)s %(levelname)-8s %(message)s')
logging.debug('Connecting to Redis server')
rconn = redis.StrictRedis(host=rhost, port=rport, password=rpass, db=0)
logging.info('Connected to Redis server')
application = CandolintHooks(rconn, args.debug)
application.listen(options.port, options.listen, xheaders=options.xheaders)
IOLoop.instance().start()
if __name__ == '__main__':
main()