Skip to content

Instantly share code, notes, and snippets.

@apskii
Last active August 29, 2015 14:03
Show Gist options
  • Save apskii/c97331d5f9300ee2ec57 to your computer and use it in GitHub Desktop.
Save apskii/c97331d5f9300ee2ec57 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3.4
import sys
import asyncio as aio
import concurrent.futures as cf
from getpass import getpass
from itertools import takewhile
import github3
POLL_DELAY_SEC = 10
POLL_COMMITS_NUM = 10
TARGETS = {'apsk': ['onesky-scala', 'fau']}
loop = aio.get_event_loop()
commits = {} # repo.id : last_commit.sha
github = github3.login(input('Login: '), getpass('Password: '))
def last_commits_data(username, reponame):
repo = github.repository(username, reponame)
if not repo:
raise ValueError("Repository {}/{} doesn't exist!".format(username, reponame))
try:
def extract_data(repo_commit):
commit = repo_commit.commit
return repo.id, repo.owner.login, repo.name, commit.sha, commit.author['name'], commit.message
return list(map(extract_data, repo.iter_commits(number=POLL_COMMITS_NUM)))
except github3.GitHubError:
return []
@aio.coroutine
def command_listener():
reader = aio.StreamReader(loop=loop)
protocol = aio.StreamReaderProtocol(reader, loop=loop)
yield from loop.connect_read_pipe(lambda: protocol, sys.stdin)
while True:
cmd, *args = (yield from reader.readline()).decode('utf-8').strip().split(' ')
if cmd == 'quit':
loop.stop()
return
elif cmd == 'help':
print('quit - you know it')
print('set-delay <sec> - set the delay for worker polling to specified number of seconds')
elif cmd == 'set-delay':
global POLL_DELAY_SEC
POLL_DELAY_SEC = int(args[0])
@aio.coroutine
def commit_watcher():
pp_executor = cf.ProcessPoolExecutor()
while True:
tasks = []
for username, reponames in TARGETS.items():
for reponame in reponames:
tasks.append(loop.run_in_executor(pp_executor, last_commits_data, username, reponame))
for future in aio.as_completed(tasks):
new_commits_data = []
try:
is_not_current = lambda data: commits.get(data[0], None) != data[3]
new_commits_data = list(takewhile(is_not_current, (yield from future)))
except Exception as e:
print('Error: {}'.format(e))
finally:
for id, owner_name, repo_name, sha, author_name, msg in reversed(new_commits_data):
print("* {}/{} - {}: {}\n".format(owner_name, repo_name, author_name, msg))
if new_commits_data:
commits[id] = new_commits_data[0][3]
sys.stdout.flush()
yield from aio.sleep(POLL_DELAY_SEC, loop=loop)
print('Type "help" for the list of commands.')
print('Polling for updates...\n')
try:
loop.run_until_complete(aio.wait([command_listener(), commit_watcher()]))
except:
pass
finally:
print('Bye-bye!')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment