Files
darkfi/bin/darkirc/script/bots/commitbot.py

145 lines
4.8 KiB
Python

# -*- coding: utf-8 -*-
from http.server import BaseHTTPRequestHandler,HTTPServer
import json
import sys
import irc
# Attributes of the server this bot will run on
SERVER_HOST = 'server.url.or.ip'
SERVER_PORT = 11022
# Attributes of the IRC connection
IRC_SERVER = '127.0.0.1'
IRC_PORT = 6667
IRC_CHANNEL = ['#dev']
IRC_NICK = 'commits-notifier'
# Set the password for your registered empty, leave empty if not applicable
# Note: freenode(and potentially other servers) want password to be of the form
# "nick:pass", so for ex. IRC_PASS = 'WfTestBot:mypass123'
IRC_PASS = ''
# a dictionary of branches push-related events should be enabled for, or empty if all are enabled
GH_PUSH_ENABLED_BRANCHES = [] # for example, ['master', 'testing', 'author/repo:branch']
# a dictionary of branches push-related events should be ignored for, or empty if all are enabled
GH_PUSH_IGNORE_BRANCHES = ['gh-pages']
# a list of push-related events the bot should post notifications for
GH_PUSH_ENABLED_EVENTS = ['push'] # no others supported for now
# a list of PR-related events the bot should post notifications for
# notice 'merged' is just a special case of 'closed'
GH_PR_ENABLED_EVENTS = ['opened', 'closed', 'reopened'] # could also add 'synchronized', 'labeled', etc.
# handle POST events from github server
# We should also make sure to ignore requests from the IRC, which can clutter
# the output with errors
CONTENT_TYPE = 'content-type'
CONTENT_LEN = 'content-length'
EVENT_TYPE = 'x-github-event'
ircc = irc.IRC()
ircc.connect(IRC_SERVER, IRC_PORT, IRC_CHANNEL, IRC_NICK)
def handle_push_event(irc, data):
if GH_PUSH_ENABLED_BRANCHES:
branch = get_branch_name_from_push_event(data)
repo = data['repository']['full_name']
repobranch = repo + ':' + branch
if not branch in GH_PUSH_ENABLED_BRANCHES:
if not repobranch in GH_PUSH_ENABLED_BRANCHES:
return
if GH_PUSH_IGNORE_BRANCHES:
branch = get_branch_name_from_push_event(data)
if branch in GH_PUSH_IGNORE_BRANCHES:
return
if 'push' in GH_PUSH_ENABLED_EVENTS:
handle_forward_push(irc, data)
def handle_pull_request(irc, data):
author = data['sender']['login']
if not data['action'] in GH_PR_ENABLED_EVENTS:
return
action = data['action']
merged = data['pull_request']['merged']
action = 'merged' if action == 'closed' and merged else action
pr_num = '#' + str(data['number'])
title = data['pull_request']['title']
print("PR event:")
print(f"@{author} {action} pull request {pr_num}: {title}")
print("==============================================")
irc.send("#dev", f"@{author} {action} pull request {pr_num}: {title}")
def get_branch_name_from_push_event(data):
return data['ref'].split('/')[-1]
def handle_forward_push(irc, data):
author = data['commits'][0]['author']['name']
num_commits = len(data['commits'])
num_commits = str(num_commits) + " commit" + ('s' if num_commits > 1 else '')
branch = get_branch_name_from_push_event(data)
commits = list(map(fmt_commit, data['commits']))
for commit in reversed(commits):
print("Push event:")
print(f"@{author} pushed {num_commits} to {branch}: {commit}")
print("==============================================")
irc.send("#dev", f"@{author} pushed {num_commits} to {branch}: {commit}")
def fmt_commit(cmt):
hsh = cmt['id'][:10]
# author = cmt['author']['name']
message = cmt['message'].split("\n")
message = message[0] \
+ ('...' if len(message) > 1 else '')
return '{}: {}'.format(hsh, message)
class MyHandler(BaseHTTPRequestHandler):
def do_GET(self):
pass
def do_CONNECT(self):
pass
def do_POST(self):
if not all(x in self.headers for x in [CONTENT_TYPE, CONTENT_LEN, EVENT_TYPE]):
return
content_type = self.headers['content-type']
content_len = int(self.headers['content-length'])
event_type = self.headers['x-github-event']
if content_type != "application/json":
self.send_error(400, "Bad Request", "Expected a JSON request")
return
data = self.rfile.read(content_len)
if sys.version_info < (3, 6):
data = data.decode()
self.send_response(200)
self.send_header('content-type', 'text/html')
self.end_headers()
self.wfile.write(bytes('OK', 'utf-8'))
if event_type == 'push':
handle_push_event(ircc, json.loads(data))
elif event_type == 'pull_request':
handle_pull_request(ircc, json.loads(data))
return
# Run Github webhook handling server
try:
server = HTTPServer((SERVER_HOST, SERVER_PORT), MyHandler)
server.serve_forever()
except KeyboardInterrupt:
print("Exiting")
server.socket.close()