| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- # -*- 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()
|