Anton Shestakov <av6@dwimlabs.net>, Wed, 20 Sep 2017 11:25:26 +0800
viewer: use two columns for info lists on check page for small screens too
Since lists themselves switch to one column on small screens, there's enough
space for both of them side by side.
poller-queue.py
Permissions: -rwxr-xr-x
from argparse import ArgumentParser, FileType, SUPPRESS from urlparse import urlparse from tornado.gen import coroutine from tornado.httpclient import AsyncHTTPClient from tornado.ioloop import IOLoop, PeriodicCallback from tornado.web import Application from candolint.utils import lookup_option, timestamp parsed = urlparse(target['url']) path = parsed.path.rstrip('/') if 'source' not in target: target['source'] = parsed.hostname target['repo'] = path.rpartition('/')[-1] if target['type'] == 'hgweb': elif target['type'] == 'github': class CandolintPoller(Application): def __init__(self, rconn, targets, interval, debug): super(CandolintPoller, self).__init__(handlers, debug=debug) IOLoop.instance().add_callback(self.setup) for target in self.targets: def routine(target=target): pc = PeriodicCallback(routine, self.interval * 1000) 'User-Agent': 'Candolint poller (https://bitbucket.org/av6/candolint)' headers['If-None-Match'] = target['etag'] logging.debug('Fetching %s', target['poll']) response = yield http.fetch(target['poll'], raise_error=False, headers=headers) data = json.loads(response.body) if target['type'] == 'hgweb': self.parse_hgweb(target, data) elif target['type'] == 'github': self.parse_github(target, data) target['etag'] = response.headers.get('ETag', None) elif response.code == 304: logging.debug('Not modified: %s', target['poll']) logging.error('Error %d fetching %s', response.code, target['poll']) def parse_hgweb(self, target, data): hashes = set(branch['node'] for branch in data['branches']) new = hashes - target['hashes'] 'source': target['source'], logging.info('Got %d new hash(es) from %s', len(new), target['poll']) logging.info('Got %d current hash(es) from %s', len(hashes), target['poll']) target['hashes'] = hashes def parse_github(self, target, data): hashes = {branch['name']: branch['commit']['sha'] for branch in data} for name, sha in hashes.items(): if target['hashes'].get(name) != sha: 'source': target['source'], logging.info('Got %d new hash(es) from %s', len(new), target['poll']) logging.info('Got %d current hash(es) from %s', len(hashes), target['poll']) target['hashes'] = hashes def push(self, base, changes): logging.debug('Pushing %s', data) self.rconn.rpush('candolint:queue:changes', data) logging.info('Pushed a change for %s', item['repo']) parser = ArgumentParser(argument_default=SUPPRESS) '-c', '--config', type=FileType('r'), help='configuration file (YAML)') '-d', '--debug', action='store_true', default=False, help='enable debugging output') group = parser.add_argument_group( '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') group.add_argument('--poll-interval', type=int, help='(default: 1 hour)') args = parser.parse_args() 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) interval = lookup_option('poll-interval', args, config, default=60 * 60) level=logging.DEBUG if args.debug else logging.INFO, format='%(asctime)s %(levelname)-8s %(message)s') if config and 'targets' in config: targets = config['targets'] logging.warn('No targets defined.') logging.debug('Connecting to Redis server') rconn = redis.StrictRedis(host=rhost, port=rport, password=rpass, db=0) logging.info('Connected to Redis server') CandolintPoller(rconn, targets, interval, args.debug) IOLoop.instance().start() if __name__ == '__main__':