def listen(self): k = self.current_user.id t = config.listen_timeout repo_path = '%s/%s' % (self.owner, self.name) redis = Redis(namespace=repo_path) logging.debug('blocking waiting for %s' % k) response = redis('blpop', [k], timeout=t) if response is None: return {'status': '304'} commit_id = response[1] data = utils.json_decode(redis[commit_id]) data.update({'status': 200}) return data
def post(self): """We get a payload like this:: { "after": "0df48053b961ad6f26956ea4bbcbe27c97b7a21b", "before": "ad9aeac5f80097660619349f5dd93fb07a2b2eb0", "commits": [ { "added": [], "author": { "email": "*****@*****.**", "name": "James Arthur" }, "id": "0df48053b961ad6f26956ea4bbcbe27c97b7a21b", "message": "blah", "modified": [ "README.md" ], "removed": [], "timestamp": "2010-05-18T04:13:47-07:00", "url": "http:\/\/github.com\/thruflo\/Dummy-Bus-Dev\/commit\/0df48053b961ad6f26956ea4bbcbe27c97b7a21b" } ], "ref": "refs\/heads\/master", "repository": { "description": "Dummy user account to test github API", "fork": false, "forks": 0, "has_downloads": false, "has_issues": false, "has_wiki": false, "homepage": "http:\/\/dummy.thruflo.com", "name": "Dummy-Bus-Dev", "open_issues": 0, "owner": { "email": "*****@*****.**", "name": "thruflo" }, "private": false, "url": "http:\/\/github.com\/thruflo\/Dummy-Bus-Dev", "watchers": 1 } } We validate it by checking the commit ids against either the latest or the handled commits for that branch. """ logging.debug('PostCommitHook') # get the payload payload = self.get_argument('payload') logging.debug('payload') logging.debug(payload) data = utils.json_decode(payload) logging.debug('data') logging.debug(data) # get a handle on the repository repo = data['repository'] branch = data["ref"].split('/')[-1] path = '%s/%s' % (repo['owner']['name'], repo['name']) docid = model.Repository.get_id_from(path) # is this actually a repo we have stored? repository = model.Repository.get(docid) if repository is None: return '' logging.debug('repository') logging.debug(repository) # to validate, either the before matches the latest # sanity checked commit, or the latest handled commit latest = repository.latest_sanity_checked_commits[branch] handled = repository.handled_commits[branch] if data['before'] == latest: logging.debug('before matched latest commit') elif data['before'] in handled: logging.debug('before matched one a handled commit') else: return '' logging.debug('trying to fetch an authenticated user') users = repository.users users.reverse() for user in users: github = clients.github_factory(user=user) try: github.users.make_request('show') except RuntimeError: github = None logging.warning('@@ cache that this user failed to authenticate') else: break logging.debug('github') logging.debug(github) if github is not None: logging.debug('handling commits') relevant_commits = repository.handle_commits( github, branch, data['commits'], before=data['before'] ) logging.debug('relevant commits') logging.debug(relevant_commits) if relevant_commits: # save the repo repository.save() # augment the data with a list of invalid blob ids invalid_blobs = [] for item in relevant_commits: for k in 'removed', 'modified': for filepath in item.get(k): blob_id = model.Blob.get_id_from( repository.path, branch, filepath ) invalid_blobs.append(blob_id) invalid_blobs = list(set(invalid_blobs)) # notify any live users redis = Redis(namespace=repository.path) k = data['after'] v = { 'branch': branch, 'invalid_blobs': invalid_blobs, 'commits': relevant_commits } redis[k] = utils.json_encode(v) for user in repository.users: redis('rpush', user.id, k) return ''